class TestServer(unittest.TestCase): def setUp(self): self._server = Server() port = self._server.start() address = "ws://localhost:%d" % port factory = WebSocketClientFactory(address) factory.protocol = Protocol factory.setProtocolOptions(openHandshakeTimeout=0) self._connector = connectWS(factory) self._client_factory = factory def tearDown(self): self._close_deferred = defer.Deferred() return self._close_deferred def test_send_many_messages(self): self._n_messages = 5 def message_received_cb(session, message): for i in range(0, 5): session.send_message("Hello") def session_started_cb(server, session): session.connect("message-received", message_received_cb) def client_message_cb(message): self._n_messages = self._n_messages - 1 if self._n_messages == 0: self._connector.disconnect() self._close_deferred.callback(self) self._client_factory.message_cb = client_message_cb self._server.connect("session-started", session_started_cb) def test_send_one_message(self): def message_received_cb(session, message): session.send_message("Hello") def session_started_cb(server, session): session.connect("message-received", message_received_cb) def client_message_cb(message): self._connector.disconnect() self._close_deferred.callback(self) self._client_factory.message_cb = client_message_cb self._server.connect("session-started", session_started_cb)
class HTMLActivity(activity.Activity): def __init__(self, handle): activity.Activity.__init__(self, handle) self._web_view = WebKit2.WebView() self.set_canvas(self._web_view) self._web_view.show() self._authenticated = False self._server = Server() self._server.connect("session-started", self._session_started_cb) port = self._server.start() index_path = os.path.join(activity.get_bundle_path(), "index.html") self._key = os.urandom(16).encode("hex") self._web_view.load_uri("file://%s?port=%s&key=%s" % (index_path, port, self._key)) self._apis = {} self._apis["activity"] = ActivityAPI(self) def _session_started_cb(self, server, session): session.connect("message-received", self._message_received_cb) def _message_received_cb(self, session, message): request = json.loads(message.data) if request["method"] == "authenticate": if self._key == request["params"][0]: self._authenticated = True return if not self._authenticated: return api_name, method_name = request["method"].split(".") method = getattr(self._apis[api_name], method_name) result = method(*request["params"]) response = {"result": result, "error": None, "id": request["id"]} session.send_message(json.dumps(response))
class APIServer(object): def __init__(self): self._stream_monitors = {} self._server = Server() self._server.connect("session-started", self._session_started_cb) self._port = self._server.start() self._key = os.urandom(16).encode("hex") self._apis = {} self._apis["activity"] = ActivityAPI self._apis["datastore"] = DatastoreAPI def setup_environment(self): os.environ["SUGAR_APISOCKET_PORT"] = str(self._port) os.environ["SUGAR_APISOCKET_KEY"] = self._key def _open_stream(self, client, request): for stream_id in range(0, 255): if stream_id not in client.stream_monitors: client.stream_monitors[stream_id] = StreamMonitor() break client.send_result(request, [stream_id]) def _close_stream(self, client, request): stream_id = request["params"][0] stream_monitor = client.stream_monitors[stream_id] if stream_monitor.on_close: stream_monitor.on_close(request) del client.stream_monitors[stream_id] def _session_started_cb(self, server, session): session.connect("message-received", self._message_received_cb, APIClient(session)) def _message_received_cb(self, session, message, client): if message.message_type == Message.TYPE_BINARY: stream_id = ord(message.data[0]) stream_monitor = client.stream_monitors[stream_id] stream_monitor.on_data(message.data) return request = json.loads(message.data) if request["method"] == "authenticate": params = request["params"] if self._key == params[1]: client.activity_id = params[0] return activity_id = client.activity_id if activity_id is None: return if request["method"] == "open_stream": self._open_stream(client, request) elif request["method"] == "close_stream": self._close_stream(client, request) else: api_name, method_name = request["method"].split(".") getattr(self._apis[api_name](client), method_name)(request)
class APIServer(object): def __init__(self): self._stream_monitors = {} self._server = Server() self._server.connect("session-started", self._session_started_cb) self._port = self._server.start() self._key = os.urandom(16).encode("hex") self._apis = {} self._apis["activity"] = ActivityAPI self._apis["datastore"] = DatastoreAPI def setup_environment(self): os.environ["SUGAR_APISOCKET_PORT"] = str(self._port) os.environ["SUGAR_APISOCKET_KEY"] = self._key def _open_stream(self, client, request): for stream_id in xrange(0, 255): if stream_id not in client.stream_monitors: client.stream_monitors[stream_id] = StreamMonitor() break client.send_result(request, [stream_id]) def _close_stream(self, client, request): stream_id = request["params"][0] stream_monitor = client.stream_monitors[stream_id] if stream_monitor.on_close: stream_monitor.on_close(request) del client.stream_monitors[stream_id] def _session_started_cb(self, server, session): session.connect("message-received", self._message_received_cb, APIClient(session)) def _message_received_cb(self, session, message, client): if message.message_type == Message.TYPE_BINARY: stream_id = ord(message.data[0]) stream_monitor = client.stream_monitors[stream_id] stream_monitor.on_data(message.data) return request = json.loads(message.data) if request["method"] == "authenticate": params = request["params"] if self._key == params[1]: client.activity_id = params[0] return activity_id = client.activity_id if activity_id is None: return if request["method"] == "open_stream": self._open_stream(client, request) elif request["method"] == "close_stream": self._close_stream(client, request) else: api_name, method_name = request["method"].split(".") getattr(self._apis[api_name](client), method_name)(request)
class WebServer(object): def __init__(self): self._sessions = {} self._server = Server() self._server.connect('session-started', self._session_started_cb) self._port = self._server.start(_PORT) def _session_started_cb(self, server, session): # perhaps reject non-sugar connections # how do we know if a connection comes from sugar? client = WebClient(session) session.connect('handshake-completed', self._handshake_completed_cb, client) session.connect('message-received', self._message_received_cb, client) # maybe disconnect the signal handler once it is recieved if session.is_ready(): self._add_client(session, client) def _add_client(self, session, client): url = session.get_headers().get('http_path') # this should be of the form '/hub/sessionID' if not url or not url.startswith('/hub/'): return session_id = url[5:] client.set_session_id(session_id) if session_id in self._sessions: self._sessions[session_id].append(client) else: self._sessions[session_id] = [client] client.send_json_message( {'type': 'init-connection', 'peerCount': len(self._sessions[session_id])}) def _handshake_completed_cb(self, session, client): self._add_client(session, client) def _message_received_cb(self, session, message, source): if message.message_type == Message.TYPE_BINARY: # FIXME: how to handle this? return session_id = source.get_session_id() if session_id is None: # perhaps queue return dictionary = json.loads(message.data) # TODO: be more strict with the protocol for client in self._sessions[session_id]: if client != source or dictionary.get('server-echo', False): client.send_raw_message(message.data) def _session_ended_cb(self, session, client): # FIXME: this callback is not called at all self._add_client(session, client) session_id = client.get_session_id() if session_id is None: return self._sessions[session_id].remove(client) if not self._sessions[session_id]: del self._sessions[session_id]