class WSDemoServer(threading.Thread): '''A threaded wrapper around the websockets server so that we can run the Flask and Websockets in parallel together. Args: port (int): The port number for the Websockets server to run on. ''' def __init__(self, host, port): threading.Thread.__init__(self) self.log = logs.Logger('WebSocketsServer').getLogger() self.port = int(port) self.host = host self.daemon = True self.flag = True self.server = WSGIServer((self.host, self.port), WSDemoApp()) pass def run(self): '''Runs the threaded server Args: N/A Returns: N/A ''' self.log.info('Starting websockets server') self.server.serve_forever() def broadcast(self, data): '''A wrapper on the server's broadcast method so that it can be easily accessed from the flask application Args: data (str): A string message to send to the client. Returns: N/A ''' self.server.application.broadcast(data) def stop(self): '''Stops the websockets server''' self.server.stop()
def main(address=None): args = parser.parse_args() conf = create_settings(args=args) address = address or conf.get_address() print('Run', address) server = WSGIServer(address, SessionServer(handler_cls=SessionClient)) session = setup_session(server, settings=conf) server.environ['WEBSOCKET_SESSION'] = session try: server.serve_forever() except KeyboardInterrupt as e: print('.. Stopped') session.close() server.stop() server.close()
class WSDemoServer(threading.Thread): '''A threaded wrapper around the websockets server so that we can run the Flask and Websockets in parallel together. Args: port (int): The port number for the Websockets server to run on. ''' def __init__(self, host, port): threading.Thread.__init__(self) self.log = logs.Logger('WebSocketsServer').getLogger() self.port = int(port) self.host = host self.daemon = True self.flag = True self.server = WSGIServer((self.host, self.port), WSDemoApp()) pass def run(self): '''Runs the threaded server Args: N/A Returns: N/A ''' self.log.info('Starting websockets server') self.server.serve_forever() def broadcast(self, data): '''A wrapper on the server's broadcast method so that it can be easily accessed from the flask application Args: data (str): A string message to send to the client. Returns: N/A ''' self.server.application.broadcast(data) def stop(self): '''Stops the websockets server''' self.server.stop()
class WSServer(object): def __init__(self, listen, request_handler, msg_handler_pool_size=1024, indent='indented', pingpong_trigger=0, pingpong_timeout=0, keyfile=None, certfile=None): """ :param listen: string ip:port :param request_handler: instance of januscloud.proxy.core.request:RequestHandler :param msg_handler_pool_size: :param keyfile: :param certfile: """ if msg_handler_pool_size == 0: msg_handler_pool_size = None self._msg_handler_pool = Pool(size=msg_handler_pool_size) self._request_handler = request_handler self._listen = listen if keyfile or certfile: self._server = WSGIServer( self._listen, WebSocketWSGIApplication(protocols=['janus-protocol'], handler_cls=WSServerConn), log=logging.getLogger('websocket server'), keyfile=keyfile, certfile=certfile) else: self._server = WSGIServer( self._listen, WebSocketWSGIApplication(protocols=['janus-protocol'], handler_cls=WSServerConn), log=logging.getLogger('websocket server'), ) self._server.set_environ({ 'app.recv_msg_cbk': self._async_incoming_msg_handler, 'app.closed_cbk': self._request_handler.transport_gone, 'json_indent': indent, 'pingpong_trigger': pingpong_trigger, 'pingpong_timeout': pingpong_timeout }) def serve_forever(self): log.info("Starting websocket server on {0}".format(self._listen)) self._server.serve_forever() def stop(self): self._server.stop() def _async_incoming_msg_handler(self, transport_session, message, exception_handler): greenlet = Greenlet( self._incoming_msg_handler, transport_session, message, ) greenlet.link_exception(exception_handler) self._msg_handler_pool.start(greenlet, blocking=True) def _incoming_msg_handler(self, transport_session, message): if self._request_handler: response = self._request_handler.incoming_request( Request(transport_session, message)) if response: transport_session.send_message(response)
class GameServer: def __init__(self, host, port, public_address, game_id): self.host = host self.port = port self.public_address = public_address self.clients = [] self.game_id = game_id self.game = Game() self.server = WSGIServer((host, port), GameApplication(self)) self.subscribers = dict() self.subscribers["Current"] = [] self.subscribers["Past"] = [] self.subscribers["Event"] = [] self.running = True self.webserver_thread = Thread(target=self.server.serve_forever, args=(0.5,)) self.past_subscribers_thread = Thread(target=self.serve_past_subscribers) self.timeout_thread = Thread(target=self.timeout) def start(self): self.webserver_thread.start() self.past_subscribers_thread.start() self.timeout_thread.start() print "Started game server on {}, {}".format(self.host, self.port) def serve_past_subscribers(self): while self.running: for subscriber, past_state in self.subscribers["Past"]: if past_state.finished(): continue updates, events = past_state.pass_time(PAST_SEND_INTERVAL*subscriber.speed) for update in updates: subscriber.send_update(update) for event in events: subscriber.send_event(event) self.subscribers["Past"][:] = [(s, ps) for s, ps in self.subscribers["Past"] if not ps.finished()] time.sleep(PAST_SEND_INTERVAL * TIME_PER_TICK) def timeout(self): timeout = SERVICE_TIMEOUT while self.running: time.sleep(TIMEOUT_INTERVAL) print "Checking Timeout" total_subscribers = len(self.subscribers["Current"])+len(self.subscribers["Past"])+len(self.subscribers["Event"]) if total_subscribers > 0 or not self.game.complete: timeout = SERVICE_TIMEOUT else: timeout -= TIMEOUT_INTERVAL print "{}".format(timeout) if timeout < 0: print "Timeout: shutting down gameserver" self.running = False self.server.stop() print "Finished timeout-thread" def find_client(self, client_id): for client in self.clients: if client.id == client_id: return client print "Couldn't find client" return None def create_client(self): client = Client(Protocols.generate_id()) self.clients.append(client) return client def remove_client(self, client): self.remove_subscriber(client) self.clients[:] = [c for c in self.clients if c.id != client.id] def provides_game(self, game_id): return self.game_id == game_id def add_subscriber(self, client, mode, time): if mode == GameProtocol.SubscribeModes.CURRENT: self.subscribers["Event"].append(client) self.subscribers["Current"].append(client) elif mode == GameProtocol.SubscribeModes.PAST: client.set_time(time) self.subscribers["Past"].append((client, self.game.past_state(time))) def remove_subscriber(self, client): self.subscribers["Event"][:] = [c for c in self.subscribers["Event"] if c.id != client.id] self.subscribers["Current"][:] = [(s, it) for s, it in self.subscribers["Past"] if s.id != client.id] self.subscribers["Past"][:] = [(s, it) for s, it in self.subscribers["Past"] if s.id != client.id] def register_update(self, update): self.game.add_update(update) for client in self.subscribers["Current"]: client.send_update(update) def register_event(self, event): self.game.add_event(event) for client in self.subscribers["Event"]: client.send_event(event) def finish(self): self.game.finish()
} logging.exception(exception) handler = self.handler(request, response) return handler.get() app.error_handlers[403] = Webapp2HandlerAdapter(errors.Error403Handler) app.error_handlers[404] = Webapp2HandlerAdapter(errors.Error404Handler) app.error_handlers[503] = Webapp2HandlerAdapter(errors.Error503Handler) app.error_handlers[500] = Webapp2HandlerAdapter(errors.Error500Handler) if __name__ == '__main__': logger = logging.getLogger() logger.setLevel(logging.DEBUG) http_server = WSGIServer(('', 8080), app) ws_server = WSGIServer(('', 9000), WebSocketWSGIApplication(handler_cls=sample_websocket.Commands)) greenlets = [ gevent.spawn(http_server.serve_forever), gevent.spawn(utils.background_service), gevent.spawn(ws_server.serve_forever) ] try: gevent.joinall(greenlets) except KeyboardInterrupt: http_server.stop() print 'Stopping'