Permalink
Browse files

First commit - interact example works

  • Loading branch information...
0 parents commit a99e695066b53f910650e87373e1467807d99926 @gleicon committed Dec 29, 2009
Showing with 232 additions and 0 deletions.
  1. +13 −0 README
  2. +79 −0 examples/interact.html
  3. +25 −0 examples/interact.py
  4. +29 −0 setup.py
  5. +86 −0 txwebsockets/__init__.py
13 README
@@ -0,0 +1,13 @@
+Twisted WebSockets protocol
+
+- To test it, run python -m SimpleHTTPServer 8888 to serve interact.html
+- run python protocol.py and open http://localhost:8888/interact.html
+- type something in the text box
+
+
+The inspiration for a websocket server (and the test html) came from Joe Armstrong.
+
+Check interact.py to learn how to setup a basic operations class and pass it to the protocol factory.
+
+Gleicon Moraes
+
@@ -0,0 +1,79 @@
+<html>
+<head>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
+<script>
+$(document).ready(function(){
+ // from joe amstrong's websocket example
+ // http://armstrongonsoftware.blogspot.com/
+ // his ! syntax idea should be the standard for reaching tag content
+var ws;
+
+if ("WebSocket" in window) {
+ debug("Horray you have web sockets Trying to connect...");
+ ws = new WebSocket("ws://localhost:8007/websession");
+
+ ws.onopen = function() {
+ // Web Socket is connected. You can send data by send() method.
+ debug("connected...");
+ ws.send("hello from the browser");
+ ws.send("more from browser");
+ };
+
+ run = function() {
+ var val=$("#i1").val(); // read the entry
+ $("#i1").val(""); // and clear it
+ ws.send(val); // tell erlang
+ return true; // must do this
+ };
+
+ ws.onmessage = function (evt) {
+ var data = evt.data;
+ var i = data.indexOf("!");
+ var tag = data.slice(0,i);
+ var val = data.slice(i+1);
+ $("#" + tag).html(val);
+ };
+
+ ws.onclose = function() {
+ debug(" socket closed");
+ };
+} else {
+ alert("You have no web sockets");
+};
+
+ function debug(str){
+ $("#debug").append("<p>" + str);
+ };
+});
+</script>
+</head>
+<body>
+
+
+<h1>Interaction experiment</h1>
+
+<h2>Debug</h2>
+<div id="debug"></div>
+
+<fieldset>
+<legend>Last message time: </legend>
+<div id="clock"></div>
+</fieldset>
+
+<fieldset>
+<legend>out</legend>
+<div id="out">Output should appear here</div>
+</fieldset>
+
+<p>Enter something in the entry below,
+the server will send it back to the out region above
+</p>
+
+<fieldset>
+ <legend>entry</legend><!-- 42 -->
+<P>Enter: <input id="i1" onchange="run()" size ="42"></p>
+</fieldset>
+
+</body>
+</html>
+
@@ -0,0 +1,25 @@
+from txwebsockets import WebSocketFactory, BasicOperations
+import datetime
+
+class MyOperations(BasicOperations):
+
+ def on_read(self, sl, line):
+ print "read:", line
+ sl('\x00clock!%s\xff' % datetime.datetime.now())
+ sl('\x00out!%s\xff' % line)
+
+ def on_connect(self):
+ print "connected"
+
+ def on_close(self, r):
+ print "connection closed: ", r
+
+if __name__ == '__main__':
+ from twisted.internet import reactor
+ mo = MyOperations()
+
+ factory = WebSocketFactory(mo)
+
+ reactor.listenTCP(8007, factory)
+ reactor.run()
+
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+# coding: utf-8
+# (c) 2009 Gleicon Moraes
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import sys
+import distutils.core
+
+distutils.core.setup(
+ name="txwebsockets",
+ version="0.1",
+ packages = ["txwebsockets"],
+ author="Gleicon Moraes",
+ author_email="gleicon@gmail.com",
+ url="http://github.com/gleicon/txwebsockets",
+ license="http://www.apache.org/licenses/LICENSE-2.0",
+ description="twisted server protocol for websockets",
+)
@@ -0,0 +1,86 @@
+# coding: utf-8
+# (c) 2009 Gleicon Moraes
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+from twisted.protocols.basic import LineReceiver
+from twisted.internet.protocol import Factory
+import re
+
+
+class BasicOperations(object):
+ """ Basic tx websockets operations handler. Overwrite it with your operations """
+ def on_read(self, sendLine, handler):
+ pass
+ def on_connect(self):
+ pass
+ def on_close(self, r):
+ pass
+
+
+class WebSocketServer(LineReceiver):
+ HDR_ORIGIN = re.compile('Origin\:\s+(.*)')
+ HDR_LOCATION = re.compile('GET\s+(.*)\s+HTTP\/1.1', re.I)
+ HDR_HOST = re.compile('Host\:\s+(.*)')
+ def __init__(self):
+
+ self.hdr = '''HTTP/1.1 101 Web Socket Protocol Handshake\r
+Upgrade: WebSocket\r
+Connection: Upgrade\r
+WebSocket-Origin: %s\r
+WebSocket-Location: ws://%s%s\r\n\r\n'''
+
+ def connectionMade(self):
+ self.setRawMode()
+ self.factory.oper.on_connect()
+
+ def lineReceived(self, line):
+ self.factory.oper.on_read(self.sendLine, line)
+ #self.sendLine('\x00clock!%s\xff' % datetime.datetime.now())
+ #self.sendLine('\x00out!%s\xff' % line)
+
+ def rawDataReceived(self, line):
+ origin, location, host = self._parseHeaders(line)
+ print self.hdr % (origin, host, location)
+ self.sendLine(self.hdr % (origin, host, location))
+ self.delimiter='\xff'
+ self.setLineMode()
+
+ def connectionLost(self, reason):
+ self.factory.oper.on_close(reason)
+
+ def _parseHeaders(self, buf):
+ o=None
+ l=None
+ h=None
+ for a in buf.split('\n\r'):
+ print a
+ org=self.HDR_ORIGIN.search(a)
+ loc=self.HDR_LOCATION.search(a)
+ hst=self.HDR_HOST.search(a)
+ if org != None:
+ o=org.group(1).strip()
+ if hst != None:
+ h=hst.group(1).strip()
+ if loc != None:
+ l=loc.group(1).strip()
+ return o,l,h
+
+class WebSocketFactory(Factory):
+ protocol = WebSocketServer
+
+ def __init__(self, oper=BasicOperations):
+ self.oper=oper
+
+

0 comments on commit a99e695

Please sign in to comment.