Mike Lewis 13 жил өмнө
parent
commit
3e80331003

+ 9 - 18
README.rst

@@ -152,11 +152,10 @@ websocket on port 9900.
 It's a simple project.  Uses storyboard.  Storyboard is sweet.
 
 
-Test Client Server (``wssh``)
-```````````````````````````````
-To talk to the chat client, we are going to use an app called `wssh
-<https://github.com/progrium/wssh>`_. It's somewhat like ``netcat`` but for
-websockets.
+TestChat Server
+```````````````
+We've included a small server for the chat app.  It has a simple function.
+It will take a message and broadcast it to all other connected clients.
 
 We have to get some dependencies.  We also want to reuse the virtualenv we made
 when we ran the tests. If you haven't run the tests yet, go into the
@@ -168,19 +167,11 @@ This will set up your `virtualenv <http://pypi.python.org/pypi/virtualenv>`_.
 Now, in your terminal::
 
   source .env/bin/activate
-  brew install libevent
-  pip install \
-    git+https://github.com/Lawouach/WebSocket-for-Python \
-    git+https://github.com/progrium/wssh.git
-
-In the same terminal session, start wssh::
-
-  wssh ws://localhost:9900/ -l
+  pip install git+https://github.com/facebook/tornado.git
 
+In the same terminal session, start the chatroom server::
 
-.. Note:: 
-  After disconnecting the TestChat client you may have to ``ctrl+c`` and
-  restart wssh.
+  python TestChatServer/py/chatroom.py
 
 Chatting
 ````````
@@ -188,8 +179,8 @@ Now, start TestChat.app (just run the target in the XCode project).  If you had
 it started already you can hit the refresh button to reconnect.  It should say
 "Connected!" on top.
 
-You can type into the ``wssh`` client to communicate to the app, or type into the
-app's textview to communicate to the ``wssh``.
+To talk with the app, open up your browser to `<http://localhost:9000>` and
+start chatting.
 
 
 WebSocket Server Implementation Recommendations

+ 2 - 2
SocketRocket.xcodeproj/project.pbxproj

@@ -27,7 +27,6 @@
 		F624180214D532E0003CE997 /* libSocketRocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F6B2082D1450F597009315AF /* libSocketRocket.a */; };
 		F624180314D53449003CE997 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6A12CD51451231B00C1D980 /* CFNetwork.framework */; };
 		F624180414D53449003CE997 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6A12CD3145122FC00C1D980 /* Security.framework */; };
-		F624180514D53449003CE997 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6BDA803145900D200FE3253 /* SenTestingKit.framework */; };
 		F624180614D53451003CE997 /* libicucore.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F6C41C95145F7C4700641356 /* libicucore.dylib */; };
 		F6572126146C7B6A00D6B8A9 /* NSData+SRB64Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = F6572124146C7B6A00D6B8A9 /* NSData+SRB64Additions.m */; };
 		F6A12CD1145119B700C1D980 /* SRWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = F6A12CCF145119B700C1D980 /* SRWebSocket.h */; };
@@ -106,7 +105,6 @@
 				F624180214D532E0003CE997 /* libSocketRocket.a in Frameworks */,
 				F624180314D53449003CE997 /* CFNetwork.framework in Frameworks */,
 				F624180414D53449003CE997 /* Security.framework in Frameworks */,
-				F624180514D53449003CE997 /* SenTestingKit.framework in Frameworks */,
 				F624180614D53451003CE997 /* libicucore.dylib in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -464,6 +462,7 @@
 				IPHONEOS_DEPLOYMENT_TARGET = 5.0;
 				OTHER_LDFLAGS = "-ObjC";
 				PRODUCT_NAME = "$(TARGET_NAME)";
+				TARGETED_DEVICE_FAMILY = "1,2";
 				WRAPPER_EXTENSION = app;
 			};
 			name = Debug;
@@ -484,6 +483,7 @@
 				OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
 				OTHER_LDFLAGS = "-ObjC";
 				PRODUCT_NAME = "$(TARGET_NAME)";
+				TARGETED_DEVICE_FAMILY = "1,2";
 				WRAPPER_EXTENSION = app;
 			};
 			name = Release;

+ 6 - 1
TestChat/TCViewController.m

@@ -46,7 +46,7 @@
     _webSocket.delegate = nil;
     [_webSocket close];
     
-    _webSocket = [[SRWebSocket alloc] initWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"ws://localhost:9900"]]];
+    _webSocket = [[SRWebSocket alloc] initWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"ws://localhost:9000/chat"]]];
     _webSocket.delegate = self;
     
     self.title = @"Opening Connection...";
@@ -143,6 +143,11 @@
     return YES;
 }
 
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation;
+{
+    return YES;
+}
+
 @end
 
 @implementation TCMessage

+ 5 - 3
TestChat/en.lproj/MainStoryboard.storyboard

@@ -1,10 +1,11 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="1.0" toolsVersion="1938" systemVersion="11C74" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" initialViewController="J5d-9g-n8O">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="1.1" toolsVersion="2166" systemVersion="11D50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" initialViewController="J5d-9g-n8O">
     <dependencies>
         <development defaultVersion="4200" identifier="xcode"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="933"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="1166"/>
     </dependencies>
     <scenes>
+        <!--View Controller-->
         <scene sceneID="6me-oX-IDw">
             <objects>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="KsG-hH-48N" userLabel="First Responder" sceneMemberID="firstResponder"/>
@@ -15,7 +16,7 @@
                         <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
                         <textView key="tableFooterView" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" scrollEnabled="NO" id="rfU-78-BK7">
                             <rect key="frame" x="0.0" y="110" width="320" height="48"/>
-                            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                            <autoresizingMask key="autoresizingMask" widthSizable="YES"/>
                             <color key="backgroundColor" red="0.90196079015731812" green="0.90196079015731812" blue="0.90196079015731812" alpha="1" colorSpace="calibratedRGB"/>
                             <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
                             <fontDescription key="fontDescription" type="boldSystem" pointSize="14"/>
@@ -97,6 +98,7 @@
             </objects>
             <point key="canvasLocation" x="676" y="93"/>
         </scene>
+        <!--Navigation Controller-->
         <scene sceneID="nGX-KT-vxI">
             <objects>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="DyG-Ww-kME" userLabel="First Responder" sceneMemberID="firstResponder"/>

+ 77 - 0
TestChatServer/py/chatroom.py

@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+import tornado
+import tornado.web
+import tornado.websocket
+import tornado.options
+
+import os
+
+import json
+import uuid
+
+import argparse
+
+import logging
+
+logger = logging.getLogger('gateway')
+
+args = None
+
+def parse_args():
+    global args
+    static_path = os.path.abspath(os.path.join(os.path.dirname(__file__), 'static'))
+    parser = argparse.ArgumentParser(description='Gateway server')
+
+    parser.add_argument('-v', '--verbose', help='verbose logging', action='store_true')
+
+    parser.add_argument('-s', '--static-path', help='path for static files [default: %(default)s]', default=static_path)
+
+    parser.add_argument('-p', '--listen-port', help='port to listen on [default: %(default)s]', default=9000, type=int, metavar='PORT')
+    parser.add_argument('-i', '--listen-interface', help='interface to listen on. [default: %(default)s]', default='0.0.0.0', metavar='IFACE')
+
+    args = parser.parse_args()
+    
+    
+connections = set()
+ 
+class ChatHandler(tornado.websocket.WebSocketHandler):
+    def open(self):
+        connections.add(self)
+        return None
+
+    def on_message(self, msg):
+        for c in connections:
+            if c is self:
+                continue
+            c.write_message(msg)
+
+    def on_close(self):
+        connections.remove(self)
+
+
+def main():
+    global logger
+    #tornado.options.parse_command_line()
+
+    parse_args()
+
+    if args.verbose:
+        tornado.options.enable_pretty_logging()
+        logger = logging.getLogger()
+        logger.setLevel(logging.INFO)
+
+
+    application = tornado.web.Application([
+        (r"/chat", ChatHandler),
+        (r"/(.*)", tornado.web.StaticFileHandler, {"path": args.static_path, "default_filename":'index.html'}),
+    ],
+    )
+
+
+    print "Listening on %s:%s" % (args.listen_interface, args.listen_port)
+    application.listen(args.listen_port, args.listen_interface)
+    tornado.ioloop.IOLoop.instance().start()
+
+
+if __name__ == "__main__":
+    main()

+ 1 - 0
TestChatServer/py/static/.gitignore

@@ -0,0 +1 @@
+devtools/

+ 38 - 0
TestChatServer/py/static/index.html

@@ -0,0 +1,38 @@
+<!DOCTYPE HTML>
+<html>
+  <head>
+    <script src='proxy.js'>
+    </script>
+    <style type='text/css'>
+      html {
+        background-color: rgb(48,48, 48);
+        color: rgb(221, 190, 120);
+        font-family: "HelveticaNeue", Helvetica, Arial;
+      }
+
+      a {
+        color: rgb(193, 127, 128);
+      }
+      #info_div {
+        font-size:small;
+        color: rgb(108, 144, 100);
+      }
+
+      .device_details {
+        font-size:small;
+      }
+    </style>
+  </head>
+  <body>
+    <h3>Chat History</h3>
+    <ul id='history'>
+    </ul>
+    <form id="msg_form">
+      <input type='text' name='message' id='msg_field'/>
+      <input type='submit'/>
+    </form>
+
+    <ul id='client_list'></ul>
+    <div id='info_div'></div>
+  </body>
+</html>

+ 73 - 0
TestChatServer/py/static/proxy.js

@@ -0,0 +1,73 @@
+
+function SocketClient () {
+  this.list_elem = document.getElementById('client_list');
+  this.info_div = document.getElementById('info_div');
+  var self = this;
+}
+
+SocketClient.prototype.connect = function () {
+  var self = this;
+
+  this.list_elem.innerHTML = '';
+  this.info_div.innerHTML = 'status: connecting...'; 
+  this.socket = new WebSocket("ws://" + document.location.host + "/chat");  
+  
+  this.socket.onopen = function () {self.onopen.apply(self, arguments);};
+  this.socket.onmessage = function () {self.onmessage.apply(self, arguments);};
+  this.socket.onclose = function () {self.onclose.apply(self, arguments);};
+};
+
+SocketClient.prototype.deviceAdded = function (params) {
+  var el = document.createElement('li');
+  el.innerHTML = '<a href="devtools/devtools.html?host=' + document.location.host + '&page=' + params.page + '">' + params.device_name + '</a>' + ' <span class="device_details">(' + params.app_id + ', ' + params.device_model + ', ' + params.device_id + ')</span>';
+  this.list_elem.appendChild(el);
+  this.visibleElems[params.connection_id] = el;
+};
+
+SocketClient.prototype.deviceRemoved = function (params) {
+  var li = this.visibleElems[params.connection_id];
+  li.parentNode.removeChild(li);
+};
+
+SocketClient.prototype.onopen = function () {
+  this.info_div.innerHTML = 'status: connected to gateway';
+  this.list_elem.innerHTML = '';
+  this.visibleElems = {};
+  console.log('connection to gateway opened');
+};
+
+SocketClient.prototype.onmessage = function (message) {
+  var el = document.createElement('li');
+  el.innerHTML = message.data;
+  window.document.getElementById('history').appendChild(el);
+};
+
+SocketClient.prototype.onclose = function () {
+  var retryInterval = 1000.0;
+  console.log('connection closed, retrying in ' + (retryInterval/1000.0) + ' seconds');
+  var self = this;
+  window.setTimeout(function () {self.connect();}, retryInterval);
+};
+
+
+window.addEventListener('load', function () {
+    var form = window.document.getElementById('msg_form');
+    var msg_field = window.document.getElementById('msg_field');
+
+    var socketClient = new SocketClient();
+    socketClient.connect()
+
+    form.onsubmit = function () {
+      msg = msg_field.value;
+      msg_field.value = '';
+
+      socketClient.socket.send(msg);
+
+      var el = document.createElement('li');
+      el.innerHTML = msg;
+      window.document.getElementById('history').appendChild(el);
+
+      return false;
+    };
+  }
+);