async def chat(request, ws: WebSocketCommonProtocol): print('Connected to WS Server!') print(request) print(ws) user_id = request.args.get('user_id') nickname = request.args.get('nickname') # 1. Authenticate User (create_or_update) db = app.db await db.users.update_one({'user_id': user_id}, {'$set': { 'nickname': nickname }}, True) await ws.send( ujson.dumps({ 'type': 'LOGIN', 'user_id': user_id, 'nickname': nickname, 'profile_url': 'https://sendbird.com/main/img/profiles/profile_11_512px.png', 'ping_interval': 15, 'pong_timeout': 5, 'reconnect_interval': 3 })) # 2. PING/PONG while True: try: msg = await asyncio.wait_for(ws.recv(), timeout=90.0) loaded_msg = ujson.loads(msg) await message_handler(loaded_msg, ws) except Exception as e: # TODO: leave user from channel logging.error('WS RECV Error: ' + repr(e)) break
async def _ws(self, sanic_request: SanicRequest, ws: WebSocket): recv = None pending = set() def sender(notification: Notification) -> Future: return ensure_future( self._ws_notification(sender_ctx(notification))) notifier = Notifier(ws, sender, self._finalise_future) root_ctx = Context(self.app, sanic_request, ws, notifier) sender_ctx = root_ctx(Directions.outgoing) while ws.open: if recv not in pending: recv = ensure_future(ws.recv()) pending.add(recv) try: done, pending = await wait(pending, return_when=FIRST_COMPLETED) except CancelledError: for fut in pending: self._finalise_future(fut) break for fut in done: result = self._finalise_future(fut) if not result: continue if isinstance(result, Response): pending.add(self._ws_outgoing(root_ctx(result))) continue obj = self._parse_json(result) if isinstance(obj, Response): pending.add(self._ws_outgoing(root_ctx(obj))) continue incoming = self._parse_message(obj) if isinstance(incoming, Response): pending.add(self._ws_outgoing(root_ctx(incoming))) continue ctx = root_ctx(incoming) if not self._handle_incoming( ctx, lambda x: pending.add(self._ws_outgoing(ctx(x))), pending.add): continue notifier.cancel() for fut in pending: fut.cancel()
async def _consumer_handler(self, websocket: websockets.WebSocketCommonProtocol): # the connection object to receive messages from and add them ito the queue. try: while True: # conn_list : Create a list of connected clients msg = await asyncio.wait_for(websocket.recv(), timeout=10.0) # register websocket await websocket.send(msg) self.USERS.add(websocket) self.first_conn_count += 1 print("connected websocket!") except asyncio.TimeoutError: print("finished! connected client!", str(self.first_conn_count))
async def accept_connection(self, websocket: WebSocketCommonProtocol): while True: try: request = await asyncio.wait_for(websocket.recv(), timeout=0.01) except TimeoutError: pass except ConnectionClosedOK: return else: parsed_request = json.loads(request) if 'type' in parsed_request and parsed_request['type'] == RequestType.SUBSCRIBE.value: Logger.success('[Websocket Server]: new connection was added, {}'.format(websocket.local_address)) self.connections.append(websocket) finally: await asyncio.sleep(1)
async def receive_message(self, app, ws: WebSocketCommonProtocol): return ws.recv()