def _queue_command(self, cmd): """Queue the command until the connection is ready to write to again. """ logger.info("[%s] Queing as conn %r, cmd: %r", self.id(), self.state, cmd) self.pending_commands.append(cmd) if len(self.pending_commands) > self.max_line_buffer: # The other side is failing to keep up and out buffers are becoming # full, so lets close the connection. # XXX: should we squawk more loudly? logger.error("[%s] Remote failed to keep up", self.id()) self.send_command(ErrorCommand("Failed to keep up"), do_buffer=False) self.close()
async def websocket_handler(request): ws = web.WebSocketResponse() try: await ws.prepare(request) except web.HTTPException as e: logging.info('Failed to open WebSocket') else: user_id = await authorized_userid(request) logging.info( "websocket connection opened with user_id {}".format(user_id)) # if already connected, not permit connection try: global_playground.register(user_id) except AlreadyRegistered: logging.info( "Deliberately closed connection with already connected user_id {}!" .format(user_id)) await send_command( ErrorCommand(user_id, msg=f'User id {user_id} already in use')) await ws.close() else: registry.add_socket(user_id, ws) async for msg in ws: if msg.type == WSMsgType.TEXT: await handle_command(json.loads(msg.data), user_id) elif msg.type == WSMsgType.ERROR: logging.info( 'connection closed with exception {} with user_id {}'. format(ws.exception(), user_id)) await handle_error(user_id) elif msg.type == WSMsgType.BINARY: logging.info('Received BINARY type message') elif msg.type == WSMsgType.CLOSE: logging.info('Received CLOSE type message') elif msg.type == WSMsgType.CLOSED: logging.info('Received CLOSED type message') elif msg.type == WSMsgType.CLOSING: logging.info('Received CLOSING type message') elif msg.type == WSMsgType.CONTINUATION: logging.info('Received CONTINUATION type message') elif msg.type == WSMsgType.PING: logging.info('Received PING type message') elif msg.type == WSMsgType.PONG: logging.info('Received PONG type message') logging.info( 'websocket connection closed with user_id {}'.format(user_id)) await handle_error(user_id) return ws
def send_error(self, error_string, *args): """Send an error to remote and close the connection. """ self.send_command(ErrorCommand(error_string % args)) self.close()