Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Initial commit of files.

  • Loading branch information...
commit 24baab47f13b7d46bc54f692c4536a9205a1e937 0 parents
@mheadd mheadd authored
20 LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2011 Voxeo Corporation
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 readme.md
@@ -0,0 +1,29 @@
+Overview
+========
+
+A simple application demonstrating the power of combining Tropo, Redis, Node.js and jQuery.
+
+Usage
+=====
+
+You'll need to following to run this example:
+
+* A Tropo account (Create one for free or login at [Tropo.com](http://tropo.com/).
+* An instance of Redis that external sources can connect to - [Redis to Go](https://redistogo.com/) is a good way to get this piece.
+* A server running Node.js - this example was tested with v0.4.3.
+* A webserver to serve the file socket.html (the HTML + jQuery page in this solution).
+
+You will need to modify the files "tropo-redis.php" and "socket.js" to add the settings for your Reids instance.
+Create a new Tropo Scripting application and use the "tropo-redis.php" file as the source file for the application.
+Launch the file "socket.js" using Node.js (by default, this server will listen on localhost port 8000, change this if needed):
+
+ node path/to/socket.js
+
+If you are not running your socket.js server on localhost at port 8000, you will need to modify the file "socket.html" to point to your socket.io instance.
+Once your socket.js server is running, load the socket.html page in your web browser.
+You should now be able to call into your Tropo application (via the Skype number auto provisioned for your app, or by adding a phone number).
+
+Feedback
+========
+
+Feedback is appreciated. Send to mheadd [at] voxeo [dot] com.
163 redis.php
@@ -0,0 +1,163 @@
+<?php
+/**
+ *
+ * Simple PHP class for Redis (stand alone version)
+ * Adapted from Redis.php by Ludovico Magnocavallo. (http://redis.io/topics/twitter-clone)
+ * @author Mark Headd
+ *
+ */
+class Redis {
+
+ // Private class members.
+ private $server;
+ private $port;
+ private $sock;
+ private $auth;
+
+ /**
+ *
+ * Class consrtuctor
+ * @param string $host
+ * @param int $port
+ */
+ function __construct($host='localhost', $port=6379) {
+ $this->host = $host;
+ $this->port = $port;
+ }
+
+ /**
+ *
+ * Connect to a Redis server.
+ */
+ public function connect() {
+ if ($this->sock)
+ return;
+ if ($sock = fsockopen($this->host, $this->port, $errno, $errstr)) {
+ $this->sock = $sock;
+ return;
+ }
+ $msg = "Cannot open socket to {$this->host}:{$this->port}";
+ if ($errno || $errmsg) {
+ $msg .= "," . ($errno ? " error $errno" : "") . ($errmsg ? " $errmsg" : "");
+ }
+ trigger_error("$msg.", E_USER_ERROR);
+ }
+
+ /**
+ *
+ * Set authentication credentials
+ * @param string $password
+ */
+ public function auth($password) {
+ $this->auth = $password;
+ }
+
+ /**
+ *
+ * Disconnect from a Redis server.
+ */
+ public function disconnect() {
+ if ($this->sock)
+ @fclose($this->sock);
+ $this->sock = null;
+ }
+
+ /**
+ *
+ * Publish a message on a channel.
+ * @param string $channel
+ * @param string $message
+ */
+ public function publish($channel, $message) {
+
+ // Connect to the server.
+ $this->connect();
+
+ // Authenticate.
+ if($this->auth) {
+ $this->doAuth($this->auth);
+ }
+
+ // Publish message.
+ $this->write("PUBLISH $channel $message\r\n");
+ return $this->get_response();
+
+ }
+
+ /**
+ *
+ * Private methods.
+ *
+ */
+
+ private function doAuth($auth) {
+ $this->write("AUTH $auth\r\n");
+ }
+
+ private function write($s) {
+ while ($s) {
+ $i = fwrite($this->sock, $s);
+ if ($i == 0) // || $i == strlen($s))
+ break;
+ $s = substr($s, $i);
+ }
+ }
+
+ private function read($len=1024) {
+ if ($s = fgets($this->sock))
+ return $s;
+ $this->disconnect();
+ trigger_error("Cannot read from socket.", E_USER_ERROR);
+ }
+
+ private function get_response() {
+ $data = trim($this->read());
+ $c = $data[0];
+ $data = substr($data, 1);
+ switch ($c) {
+ case '-':
+ trigger_error(substr($data, 0, 4) == 'ERR ' ? substr($data, 4) : $data, E_USER_ERROR);
+ break;
+ case '+':
+ return $data;
+ case '*':
+ $num = (int)$data;
+ if ((string)$num != $data)
+ trigger_error("Cannot convert multi-response header '$data' to integer", E_USER_ERROR);
+ $result = array();
+ for ($i=0; $i<$num; $i++)
+ $result[] =& $this-get_value();
+ return $result;
+ default:
+ return $this->get_value($c . $data);
+ }
+ }
+
+ private function get_value($data=null) {
+ if ($data === null)
+ $data =& trim($this->read());
+ if ($data == '$-1')
+ return null;
+ $c = $data[0];
+ $data = substr($data, 1);
+ $i = strpos($data, '.') !== false ? (int)$data : (float)$data;
+ if ((string)$i != $data)
+ trigger_error("Cannot convert data '$c$data' to integer", E_USER_ERROR);
+ if ($c == ':')
+ return $i;
+ if ($c != '$')
+ trigger_error("Unkown response prefix for '$c$data'", E_USER_ERROR);
+ $buffer = '';
+ while (true) {
+ $data =& $this->read();
+ $i -= strlen($data);
+ $buffer .= $data;
+ if ($i < 0)
+ break;
+ }
+ return substr($buffer, 0, -2);
+ }
+
+}
+
+?>
62 socket.html
@@ -0,0 +1,62 @@
+<html>
+<head>
+<!-- A simple HTML page with jQuery logic to connect to a socket.io instance and receive updates. -->
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
+<script type="text/javascript" src="http://127.0.0.1:8000/socket.io/socket.io.js"></script>
+<script type="text/javascript">
+$(document).ready(function() {
+
+ // Create a new connection
+ var socket = new io.Socket('127.0.0.1', {
+ port : 8000
+ });
+ socket.connect();
+
+ // Display connected text.
+ socket.on('connect', function() {
+ console.log('Connected to server...');
+ $("#connect").append("<p>Connected to Server!</p>");
+ });
+
+ // When we get a message, add the appropirate CSS class.
+ socket.on('message', function(data) {
+ console.log('Received a message from the server: ' + data);
+ $("#color").addClass(data);
+ });
+
+});
+</script>
+<style type="text/css">
+
+body {
+ background-color: red;
+ text-align: center;
+}
+
+h2 {
+ margin-top: 30px;
+}
+
+.blue {
+ background-color: blue;
+}
+
+.green {
+ background-color: green;
+}
+
+.yellow {
+ background-color: yellow;
+}
+
+.white {
+ background-color: white;
+}
+
+</style>
+</head>
+<body id="color">
+<h2>Redis PubSub + Socket.io Test</h2>
+<div id="connect"></div>
+</body>
+</html>
52 socket.js
@@ -0,0 +1,52 @@
+/*
+ * Socket IO server / Redis client.
+ * Allows connections from HTML page ans sets up a subscriber client on a Redis instance.
+ *
+ */
+
+// Include require modules.
+var io = require('socket.io');
+var redis = require('redis');
+var http = require('http');
+var sys = require('sys');
+
+// Redis config settings.
+var redisHost = '';
+var redisPort = 6379;
+var redisPass = '';
+
+// Create a web server for Socket IO to use.
+var server = http.createServer(function(req, res){
+ res.writeHead(200, {'Content-Type': 'text/html'});
+ res.end('<h1>This is a node web server.</h1>');
+});
+
+// Specify the port the server should listen on.
+server.listen(8000);
+
+// Create a new socket
+var socket = io.listen(server);
+
+// Listen for connection from clients.
+socket.on('connection', function(client){
+
+ // A client has connected.
+ sys.puts('Got a new connection!');
+
+ // Create a Redis client and subscribe.
+ var redisClient = redis.createClient(redisPort, redisHost);
+ redisClient.auth(redisPass);
+ redisClient.subscribe("tropo.color");
+
+ // Handler for Redis client subscription.
+ redisClient.on("subscribe", function (channel) {
+ sys.puts("Redis Client Subscribed to " + channel);
+ });
+
+ // When a message comes in on the subscribed channel, send it to the connected web client.
+ redisClient.on("message", function (channel, message) {
+ sys.puts("redisClient channel " + channel + ": message " + message);
+ client.send(message);
+ });
+
+});
156 tropo-redis.php
@@ -0,0 +1,156 @@
+<?php
+
+/*
+ * A simple PHP script to allow speech recongition of color selections.
+ * Publishes selections on a Tropoi channel through a persistent socket connection.
+ *
+ */
+
+// Redis settings
+define("REDIS_HOST", "");
+define("REDIS_PORT", 0000);
+define("REDIS_PASS", "");
+
+$redis = new Redis(REDIS_HOST, REDIS_PORT);
+$redis->connect();
+$redis->auth(REDIS_PASS);
+
+say("Welcome to the Redis and socket I O test.");
+
+do {
+
+ $result = ask("Say the color you want to see. When done, say stop.", array("choices" => "white, blue, green, yellow, stop"));
+ _log("*** User selected: ".$result->value." ***");
+ $response = $redis->publish("tropo.color", $result->value);
+
+} while ($result->value != 'stop');
+
+$redis->disconnect();
+say("Goodbye.");
+hangup();
+
+class Redis {
+
+ // Private class members.
+ private $server;
+ private $port;
+ private $sock;
+ private $auth;
+
+ function __construct($host='localhost', $port=6379) {
+ $this->host = $host;
+ $this->port = $port;
+ }
+
+ public function connect() {
+ if ($this->sock)
+ return;
+ if ($sock = fsockopen($this->host, $this->port, $errno, $errstr)) {
+ $this->sock = $sock;
+ return;
+ }
+ $msg = "Cannot open socket to {$this->host}:{$this->port}";
+ if ($errno || $errmsg) {
+ $msg .= "," . ($errno ? " error $errno" : "") . ($errmsg ? " $errmsg" : "");
+ }
+ trigger_error("$msg.", E_USER_ERROR);
+ }
+
+ public function auth($password) {
+ $this->auth = $password;
+ }
+
+ public function disconnect() {
+ if ($this->sock)
+ @fclose($this->sock);
+ $this->sock = null;
+ }
+
+ public function publish($channel, $message) {
+
+ // Connect to the server.
+ $this->connect();
+
+ // Authenticate.
+ if($this->auth) {
+ $this->doAuth($this->auth);
+ }
+
+ // Publish message.
+ $this->write("PUBLISH $channel $message\r\n");
+ return $this->get_response();
+
+ }
+
+ private function doAuth($auth) {
+ $this->write("AUTH $auth\r\n");
+ }
+
+ private function write($s) {
+ while ($s) {
+ $i = fwrite($this->sock, $s);
+ if ($i == 0) // || $i == strlen($s))
+ break;
+ $s = substr($s, $i);
+ }
+ }
+
+ private function read($len=1024) {
+ if ($s = fgets($this->sock))
+ return $s;
+ $this->disconnect();
+ trigger_error("Cannot read from socket.", E_USER_ERROR);
+ }
+
+ private function get_response() {
+ $data = trim($this->read());
+ $c = $data[0];
+ $data = substr($data, 1);
+ switch ($c) {
+ case '-':
+ trigger_error(substr($data, 0, 4) == 'ERR ' ? substr($data, 4) : $data, E_USER_ERROR);
+ break;
+ case '+':
+ return $data;
+ case '*':
+ $num = (int)$data;
+ if ((string)$num != $data)
+ trigger_error("Cannot convert multi-response header '$data' to integer", E_USER_ERROR);
+ $result = array();
+ for ($i=0; $i<$num; $i++)
+ $result[] =& $this-get_value();
+ return $result;
+ default:
+ return $this->get_value($c . $data);
+ }
+ }
+
+ private function get_value($data=null) {
+ if ($data === null)
+ $data =& trim($this->read());
+ if ($data == '$-1')
+ return null;
+ $c = $data[0];
+ $data = substr($data, 1);
+ $i = strpos($data, '.') !== false ? (int)$data : (float)$data;
+ if ((string)$i != $data)
+ trigger_error("Cannot convert data '$c$data' to integer", E_USER_ERROR);
+ if ($c == ':')
+ return $i;
+ if ($c != '$')
+ trigger_error("Unkown response prefix for '$c$data'", E_USER_ERROR);
+ $buffer = '';
+ while (true) {
+ $data =& $this->read();
+ $i -= strlen($data);
+ $buffer .= $data;
+ if ($i < 0)
+ break;
+ }
+ return substr($buffer, 0, -2);
+ }
+
+}
+
+
+?>
Please sign in to comment.
Something went wrong with that request. Please try again.