async def websocket_handshake(self, request): # let the websockets package do the handshake with the client headers = [] def get_header(k): return request.headers.get(k, '') def set_header(k, v): headers.append((k, v)) try: key = handshake.check_request(get_header) handshake.build_response(set_header, key) except InvalidHandshake: raise InvalidUsage('Invalid websocket request') # write the 101 response back to the client rv = b'HTTP/1.1 101 Switching Protocols\r\n' for k, v in headers: rv += k.encode('utf-8') + b': ' + v.encode('utf-8') + b'\r\n' rv += b'\r\n' request.transport.write(rv) # hook up the websocket protocol self.websocket = WebSocketCommonProtocol( max_size=self.websocket_max_size, max_queue=self.websocket_max_queue) self.websocket.connection_made(request.transport) return self.websocket
class WebSocketProtocol(HttpProtocol): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.websocket = None def connection_timeout(self): # timeouts make no sense for websocket routes if self.websocket is None: super().connection_timeout() def connection_lost(self, exc): if self.websocket is not None: self.websocket.connection_lost(exc) super().connection_lost(exc) def data_received(self, data): if self.websocket is not None: # pass the data to the websocket protocol self.websocket.data_received(data) else: try: super().data_received(data) except HttpParserUpgrade: # this is okay, it just indicates we've got an upgrade request pass def write_response(self, response): if self.websocket is not None: # websocket requests do not write a response self.transport.close() else: super().write_response(response) async def websocket_handshake(self, request): # let the websockets package do the handshake with the client headers = [] def get_header(k): return request.headers.get(k, '') def set_header(k, v): headers.append((k, v)) try: key = handshake.check_request(get_header) handshake.build_response(set_header, key) except InvalidHandshake: raise InvalidUsage('Invalid websocket request') # write the 101 response back to the client rv = b'HTTP/1.1 101 Switching Protocols\r\n' for k, v in headers: rv += k.encode('utf-8') + b': ' + v.encode('utf-8') + b'\r\n' rv += b'\r\n' request.transport.write(rv) # hook up the websocket protocol self.websocket = WebSocketCommonProtocol() self.websocket.connection_made(request.transport) return self.websocket
async def socket_coroutine(socket: websockets.WebSocketCommonProtocol, path, network_queue: asyncio.Queue): print(f'Accepted TCP connection from {socket.remote_address}') while True: try: data = await network_queue.get() await socket.send(f"{json.dumps(data)}") finally: socket.close()
def switch_protocols(): ws_protocol = WebSocketCommonProtocol() transport._protocol = ws_protocol ws_protocol.connection_made(transport) # Ensure aiohttp doesn't interfere. http_protocol.transport = None asyncio. async (run_ws_handler(ws_protocol))
async def websocket_handshake(self, request, subprotocols=None): # let the websockets package do the handshake with the client headers = {} try: key = handshake.check_request(request.headers) handshake.build_response(headers, key) except InvalidHandshake: raise InvalidUsage("Invalid websocket request") subprotocol = None if subprotocols and "Sec-Websocket-Protocol" in request.headers: # select a subprotocol client_subprotocols = [ p.strip() for p in request.headers["Sec-Websocket-Protocol"].split(",") ] for p in client_subprotocols: if p in subprotocols: subprotocol = p headers["Sec-Websocket-Protocol"] = subprotocol break # write the 101 response back to the client rv = b"HTTP/1.1 101 Switching Protocols\r\n" for k, v in headers.items(): rv += k.encode("utf-8") + b": " + v.encode("utf-8") + b"\r\n" rv += b"\r\n" request.transport.write(rv) # hook up the websocket protocol self.websocket = WebSocketCommonProtocol( close_timeout=self.websocket_timeout, max_size=self.websocket_max_size, max_queue=self.websocket_max_queue, read_limit=self.websocket_read_limit, write_limit=self.websocket_write_limit, ping_interval=self.websocket_ping_interval, ping_timeout=self.websocket_ping_timeout, ) # we use WebSocketCommonProtocol because we don't want the handshake # logic from WebSocketServerProtocol; however, we must tell it that # we're running on the server side self.websocket.is_client = False self.websocket.side = "server" self.websocket.subprotocol = subprotocol self.websocket.connection_made(request.transport) self.websocket.connection_open() return self.websocket
async def websocket_handshake(self, request): # let the websockets package do the handshake with the client headers = [] def get_header(k): return request.headers.get(k, '') def set_header(k, v): headers.append((k, v)) try: key = handshake.check_request(get_header) handshake.build_response(set_header, key) except InvalidHandshake: raise InvalidUsage('Invalid websocket request') # write the 101 response back to the client rv = b'HTTP/1.1 101 Switching Protocols\r\n' for k, v in headers: rv += k.encode('utf-8') + b': ' + v.encode('utf-8') + b'\r\n' rv += b'\r\n' request.transport.write(rv) # hook up the websocket protocol self.websocket = WebSocketCommonProtocol( max_size=self.websocket_max_size, max_queue=self.websocket_max_queue ) self.websocket.connection_made(request.transport) return self.websocket
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 websocket_handshake(self, request, subprotocols=None): # let the websockets package do the handshake with the client headers = [] def get_header(k): return request.headers.get(k, '') def set_header(k, v): headers.append((k, v)) try: key = handshake.check_request(get_header) handshake.build_response(set_header, key) except InvalidHandshake: raise InvalidUsage('Invalid websocket request') subprotocol = None if subprotocols and 'Sec-Websocket-Protocol' in request.headers: # select a subprotocol client_subprotocols = [ p.strip() for p in request.headers['Sec-Websocket-Protocol'].split(',') ] for p in client_subprotocols: if p in subprotocols: subprotocol = p set_header('Sec-Websocket-Protocol', subprotocol) break # write the 101 response back to the client rv = b'HTTP/1.1 101 Switching Protocols\r\n' for k, v in headers: rv += k.encode('utf-8') + b': ' + v.encode('utf-8') + b'\r\n' rv += b'\r\n' request.transport.write(rv) # hook up the websocket protocol self.websocket = WebSocketCommonProtocol( timeout=self.websocket_timeout, max_size=self.websocket_max_size, max_queue=self.websocket_max_queue, read_limit=self.websocket_read_limit, write_limit=self.websocket_write_limit) self.websocket.subprotocol = subprotocol self.websocket.connection_made(request.transport) self.websocket.connection_open() return self.websocket
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 websocket_handshake(self, request, subprotocols=None): headers = {} try: key = handshake.check_request(request.headers) handshake.build_response(headers, key) except InvalidHandshake: msg = "Invalid websocket request received." if self.debug: msg += "\n" + traceback.format_exc() self.logger.error(msg) self.on_response(msg) raise RuntimeError(msg) subprotocol = None if subprotocols and "Sec-Websocket-Protocol" in request.headers: # select a subprotocol client_subprotocols = [ p.strip() for p in request.headers["Sec-Websocket-Protocol"].split(",") ] for p in client_subprotocols: if p in subprotocols: subprotocol = p headers["Sec-Websocket-Protocol"] = subprotocol break # write the 101 response back to the client rv = b"HTTP/1.1 101 Switching Protocols\r\n" for k, v in headers.items(): rv += k.encode("utf-8") + b": " + v.encode("utf-8") + b"\r\n" rv += b"\r\n" request.transport.write(rv) # hook up the websocket protocol self.websocket = WebSocketCommonProtocol( timeout=self.config.ws_timeout, max_size=self.config.ws_max_size, max_queue=self.config.ws_max_queue, read_limit=self.config.ws_read_limit, write_limit=self.config.ws_write_limit, ) self.websocket.subprotocol = subprotocol self.websocket.connection_made(request.transport) self.websocket.connection_open() return self.websocket
async def websocket_handshake(self, request, subprotocols=None): # let the websockets package do the handshake with the client headers = {} try: key = handshake.check_request(request.headers) handshake.build_response(headers, key) except InvalidHandshake: raise InvalidUsage("Invalid websocket request") subprotocol = None if subprotocols and "Sec-Websocket-Protocol" in request.headers: # select a subprotocol client_subprotocols = [ p.strip() for p in request.headers["Sec-Websocket-Protocol"].split(",") ] for p in client_subprotocols: if p in subprotocols: subprotocol = p headers["Sec-Websocket-Protocol"] = subprotocol break # write the 101 response back to the client rv = b"HTTP/1.1 101 Switching Protocols\r\n" for k, v in headers.items(): rv += k.encode("utf-8") + b": " + v.encode("utf-8") + b"\r\n" rv += b"\r\n" request.transport.write(rv) # hook up the websocket protocol self.websocket = WebSocketCommonProtocol( timeout=self.websocket_timeout, max_size=self.websocket_max_size, max_queue=self.websocket_max_queue, read_limit=self.websocket_read_limit, write_limit=self.websocket_write_limit, ) self.websocket.subprotocol = subprotocol self.websocket.connection_made(request.transport) self.websocket.connection_open() return self.websocket
def data_received(self, data): try: if self.enabled: self.websocket.data_received(data) else: self.parser.feed_data(data) except HttpParserError as err: logger.debug(err) import ipdb; ipdb.set_trace() exception = panic_exceptions.InvalidUsage('Bad Request') self.write_error(exception) except HttpParserUpgrade as err: logger.debug(err) self.enabled = True response = panic_response.Response(b'') try: key = handshake.check_request(lambda x: self.headers.get(x).value) handshake.build_response(response.assimilate, key) except InvalidHandshake: exception = panic_exceptions.InvalidUsage('Invalid websocket request') self.write_error(exception) else: self.transport.write(response.channel('1.1')) self.websocket = WebSocketCommonProtocol( timeout=self.timeout, max_size=self.max_size, max_queue=self.max_queue, read_limit=self.read_limit, write_limit=self.write_limit) self.websocket.subprotocol = None #subprotocol self.websocket.connection_made(self.transport) self.websocket.connection_open() self._request_handler_task = self.params.loop.create_task( self.params.request_handler(self.request, self.websocket, self.transport))
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 websocket_handshake(self, request, subprotocols=None): # let the websockets package do the handshake with the client headers = [] def get_header(k): return request.headers.get(k, '') def set_header(k, v): headers.append((k, v)) try: key = handshake.check_request(get_header) handshake.build_response(set_header, key) except InvalidHandshake: raise InvalidUsage('Invalid websocket request') subprotocol = None if subprotocols and 'Sec-Websocket-Protocol' in request.headers: # select a subprotocol client_subprotocols = [p.strip() for p in request.headers[ 'Sec-Websocket-Protocol'].split(',')] for p in client_subprotocols: if p in subprotocols: subprotocol = p set_header('Sec-Websocket-Protocol', subprotocol) break # write the 101 response back to the client rv = b'HTTP/1.1 101 Switching Protocols\r\n' for k, v in headers: rv += k.encode('utf-8') + b': ' + v.encode('utf-8') + b'\r\n' rv += b'\r\n' request.transport.write(rv) # hook up the websocket protocol self.websocket = WebSocketCommonProtocol( max_size=self.websocket_max_size, max_queue=self.websocket_max_queue ) self.websocket.subprotocol = subprotocol self.websocket.connection_made(request.transport) self.websocket.connection_open() return self.websocket
class WebSocketProtocol(HttpProtocol): def __init__(self, *args, websocket_max_size=None, websocket_max_queue=None, **kwargs): super().__init__(*args, **kwargs) self.websocket = None self.websocket_max_size = websocket_max_size self.websocket_max_queue = websocket_max_queue # timeouts make no sense for websocket routes def request_timeout_callback(self): if self.websocket is None: super().request_timeout_callback() def response_timeout_callback(self): if self.websocket is None: super().response_timeout_callback() def keep_alive_timeout_callback(self): if self.websocket is None: super().keep_alive_timeout_callback() def connection_lost(self, exc): if self.websocket is not None: self.websocket.connection_lost(exc) super().connection_lost(exc) def data_received(self, data): if self.websocket is not None: # pass the data to the websocket protocol self.websocket.data_received(data) else: try: super().data_received(data) except HttpParserUpgrade: # this is okay, it just indicates we've got an upgrade request pass def write_response(self, response): if self.websocket is not None: # websocket requests do not write a response self.transport.close() else: super().write_response(response) async def websocket_handshake(self, request, subprotocols=None): # let the websockets package do the handshake with the client headers = [] def get_header(k): return request.headers.get(k, '') def set_header(k, v): headers.append((k, v)) try: key = handshake.check_request(get_header) handshake.build_response(set_header, key) except InvalidHandshake: raise InvalidUsage('Invalid websocket request') subprotocol = None if subprotocols and 'Sec-Websocket-Protocol' in request.headers: # select a subprotocol client_subprotocols = [ p.strip() for p in request.headers['Sec-Websocket-Protocol'].split(',') ] for p in client_subprotocols: if p in subprotocols: subprotocol = p set_header('Sec-Websocket-Protocol', subprotocol) break # write the 101 response back to the client rv = b'HTTP/1.1 101 Switching Protocols\r\n' for k, v in headers: rv += k.encode('utf-8') + b': ' + v.encode('utf-8') + b'\r\n' rv += b'\r\n' request.transport.write(rv) # hook up the websocket protocol self.websocket = WebSocketCommonProtocol( max_size=self.websocket_max_size, max_queue=self.websocket_max_queue) self.websocket.subprotocol = subprotocol self.websocket.connection_made(request.transport) self.websocket.connection_open() return self.websocket
class WebSocketProtocol(HttpProtocol): def request_timeout_callback(self): if self.websocket is None: super().request_timeout_callback() def response_timeout_callback(self): if self.websocket is None: super().response_timeout_callback() def timeout_keep_alive_handler(self): if self.websocket is None: super().timeout_keep_alive_handler() def connection_lost(self, exc): if self.websocket is not None: self.websocket.connection_lost(exc) super().connection_lost(exc) def data_received(self, data): if self.websocket is not None: self.websocket.data_received(data) else: try: super().data_received(data) except httptools.HttpParserUpgrade: pass def write_response(self, response): if self.websocket is not None: self.transport.close() else: super().on_response(response) async def websocket_handshake(self, request, subprotocols=None): headers = {} try: key = handshake.check_request(request.headers) handshake.build_response(headers, key) except InvalidHandshake: msg = "Invalid websocket request received." if self.debug: msg += "\n" + traceback.format_exc() self.logger.error(msg) self.on_response(msg) raise RuntimeError(msg) subprotocol = None if subprotocols and "Sec-Websocket-Protocol" in request.headers: # select a subprotocol client_subprotocols = [ p.strip() for p in request.headers["Sec-Websocket-Protocol"].split(",") ] for p in client_subprotocols: if p in subprotocols: subprotocol = p headers["Sec-Websocket-Protocol"] = subprotocol break # write the 101 response back to the client rv = b"HTTP/1.1 101 Switching Protocols\r\n" for k, v in headers.items(): rv += k.encode("utf-8") + b": " + v.encode("utf-8") + b"\r\n" rv += b"\r\n" request.transport.write(rv) # hook up the websocket protocol self.websocket = WebSocketCommonProtocol( timeout=self.config.ws_timeout, max_size=self.config.ws_max_size, max_queue=self.config.ws_max_queue, read_limit=self.config.ws_read_limit, write_limit=self.config.ws_write_limit, ) self.websocket.subprotocol = subprotocol self.websocket.connection_made(request.transport) self.websocket.connection_open() return self.websocket
async def receive_message(self, app, ws: WebSocketCommonProtocol): return ws.recv()
class WebSocketProtocol(asyncio.Protocol): def __init__(self, params: panic_datatypes.ServerParams): self.enabled = False self.params = params self.websocket = None self.transport = None self.timeout = params.request_timeout or 10 self.max_size = 2 ** 20 self.max_queue = 2 ** 5 self.read_limit = 2 ** 16 self.write_limit = 2 ** 16 self.url = None self.connections = params.connections self.request = None self.headers = panic_datatypes.HTTPHeaders() self.parser = HttpRequestParser(self) self._last_request_time = None self._identity = uuid.uuid4() def connection_made(self, transport): self.connections.add(self) self._timeout_handler = self.params.loop.call_later(self.timeout, self.connection_timeout) self.transport = transport self._last_request_time = datetime.datetime.utcnow() def connection_lost(self, exc): self.connections.discard(self) self._timeout_handler.cancel() self.cleanup() def cleanup(self): self.websocket = None self.transport = None self.timeout = 10 self.max_size = 1 self.max_queue = 1 self.read_limit = 2 ** 16 self.write_limit = 2 ** 16 self.enabled = False self.url = None logger.warn('handle connections') self.connections = None self.request = None self.headers = None self.parser = None self._last_request_time = None self._request_handler_task = None def connection_timeout(self): time_elapsed = datetime.datetime.utcnow() - self._last_request_time seconds_elapsed = round(time_elapsed.seconds + float('0.%d' % time_elapsed.microseconds)) if seconds_elapsed <= self.timeout: logger.info('Handler Timed out for WebSocket/Channel') #import ipdb; ipdb.set_trace() pass #if self._request_handler_task: # self._request_handler_task.cancel() #exception = panic_exceptions.RequestTimeout('Request Timeout') #self.write_error(exception) else: time_left = self.timeout - seconds_elapsed self._timeout_handler = self.params.loop.call_later(time_left, self.connection_timeout) def data_received(self, data): try: if self.enabled: self.websocket.data_received(data) else: self.parser.feed_data(data) except HttpParserError as err: logger.debug(err) import ipdb; ipdb.set_trace() exception = panic_exceptions.InvalidUsage('Bad Request') self.write_error(exception) except HttpParserUpgrade as err: logger.debug(err) self.enabled = True response = panic_response.Response(b'') try: key = handshake.check_request(lambda x: self.headers.get(x).value) handshake.build_response(response.assimilate, key) except InvalidHandshake: exception = panic_exceptions.InvalidUsage('Invalid websocket request') self.write_error(exception) else: self.transport.write(response.channel('1.1')) self.websocket = WebSocketCommonProtocol( timeout=self.timeout, max_size=self.max_size, max_queue=self.max_queue, read_limit=self.read_limit, write_limit=self.write_limit) self.websocket.subprotocol = None #subprotocol self.websocket.connection_made(self.transport) self.websocket.connection_open() self._request_handler_task = self.params.loop.create_task( self.params.request_handler(self.request, self.websocket, self.transport)) def on_url(self, url): self.url = url def on_message_complete(self): pass #self._request_handler = self.paramsself.params #self._request_handler_task = self.params.loop.create_task( # self.params.request_handler(self.request, self.write_response)) def on_header(self, name, value): self.headers.append(name.decode(), value.decode('utf-8')) def on_headers_complete(self): remote_addr = self.transport.get_extra_info('peername') if remote_addr: self.headers.append(remote_addr[0], str(remote_addr[1])) self.request = panic_request.Request( url = self.url, headers = self.headers, version = self.parser.get_http_version(), method = panic_datatypes.HTTPMethod.channel ) def write_response(self, response): self.transport.close() def request_timeout_callback(self): if self.websocket is None: return super(WebSocketProtocol, self).request_timeout_callback() def write_error(self, exception): try: response = self.params.error_handler(self.request, exception) version = self.request.version if self.request else '1.1' self.transport.write(response.output(float(version))) self.transport.close() except Exception as err: # logger.exception(err) import traceback traceback.print_stack() import ipdb;ipdb.set_trace() self.signal.stopped import sys; sys.exit(1) self.bail_out("Writing error failed, connection closed {}".format(e))
class WebSocketProtocol(HttpProtocol): def __init__( self, *args, websocket_timeout=10, websocket_max_size=None, websocket_max_queue=None, websocket_read_limit=2 ** 16, websocket_write_limit=2 ** 16, **kwargs ): super().__init__(*args, **kwargs) self.websocket = None self.websocket_timeout = websocket_timeout self.websocket_max_size = websocket_max_size self.websocket_max_queue = websocket_max_queue self.websocket_read_limit = websocket_read_limit self.websocket_write_limit = websocket_write_limit # timeouts make no sense for websocket routes def request_timeout_callback(self): if self.websocket is None: super().request_timeout_callback() def response_timeout_callback(self): if self.websocket is None: super().response_timeout_callback() def keep_alive_timeout_callback(self): if self.websocket is None: super().keep_alive_timeout_callback() def connection_lost(self, exc): if self.websocket is not None: self.websocket.connection_lost(exc) super().connection_lost(exc) def data_received(self, data): if self.websocket is not None: # pass the data to the websocket protocol self.websocket.data_received(data) else: try: super().data_received(data) except HttpParserUpgrade: # this is okay, it just indicates we've got an upgrade request pass def write_response(self, response): if self.websocket is not None: # websocket requests do not write a response self.transport.close() else: super().write_response(response) async def websocket_handshake(self, request, subprotocols=None): # let the websockets package do the handshake with the client headers = {} try: key = handshake.check_request(request.headers) handshake.build_response(headers, key) except InvalidHandshake: raise InvalidUsage("Invalid websocket request") subprotocol = None if subprotocols and "Sec-Websocket-Protocol" in request.headers: # select a subprotocol client_subprotocols = [ p.strip() for p in request.headers["Sec-Websocket-Protocol"].split(",") ] for p in client_subprotocols: if p in subprotocols: subprotocol = p headers["Sec-Websocket-Protocol"] = subprotocol break # write the 101 response back to the client rv = b"HTTP/1.1 101 Switching Protocols\r\n" for k, v in headers.items(): rv += k.encode("utf-8") + b": " + v.encode("utf-8") + b"\r\n" rv += b"\r\n" request.transport.write(rv) # hook up the websocket protocol self.websocket = WebSocketCommonProtocol( timeout=self.websocket_timeout, max_size=self.websocket_max_size, max_queue=self.websocket_max_queue, read_limit=self.websocket_read_limit, write_limit=self.websocket_write_limit, ) self.websocket.subprotocol = subprotocol self.websocket.connection_made(request.transport) self.websocket.connection_open() return self.websocket
class WebSocketProtocol(HttpProtocol): def __init__(self, *args, websocket_max_size=None, websocket_max_queue=None, **kwargs): super().__init__(*args, **kwargs) self.websocket = None self.websocket_max_size = websocket_max_size self.websocket_max_queue = websocket_max_queue def connection_timeout(self): # timeouts make no sense for websocket routes if self.websocket is None: super().connection_timeout() def connection_lost(self, exc): if self.websocket is not None: self.websocket.connection_lost(exc) super().connection_lost(exc) def data_received(self, data): if self.websocket is not None: # pass the data to the websocket protocol self.websocket.data_received(data) else: try: super().data_received(data) except HttpParserUpgrade: # this is okay, it just indicates we've got an upgrade request pass def write_response(self, response): if self.websocket is not None: # websocket requests do not write a response self.transport.close() else: super().write_response(response) async def websocket_handshake(self, request, subprotocols=None): # let the websockets package do the handshake with the client headers = [] def get_header(k): return request.headers.get(k, '') def set_header(k, v): headers.append((k, v)) try: key = handshake.check_request(get_header) handshake.build_response(set_header, key) except InvalidHandshake: raise InvalidUsage('Invalid websocket request') subprotocol = None if subprotocols and 'Sec-Websocket-Protocol' in request.headers: # select a subprotocol client_subprotocols = [p.strip() for p in request.headers[ 'Sec-Websocket-Protocol'].split(',')] for p in client_subprotocols: if p in subprotocols: subprotocol = p set_header('Sec-Websocket-Protocol', subprotocol) break # write the 101 response back to the client rv = b'HTTP/1.1 101 Switching Protocols\r\n' for k, v in headers: rv += k.encode('utf-8') + b': ' + v.encode('utf-8') + b'\r\n' rv += b'\r\n' request.transport.write(rv) # hook up the websocket protocol self.websocket = WebSocketCommonProtocol( max_size=self.websocket_max_size, max_queue=self.websocket_max_queue ) self.websocket.subprotocol = subprotocol self.websocket.connection_made(request.transport) return self.websocket
class WebSocketProtocol(HttpProtocol): def __init__( self, *args, websocket_timeout=10, websocket_max_size=None, websocket_max_queue=None, websocket_read_limit=2 ** 16, websocket_write_limit=2 ** 16, **kwargs ): super().__init__(*args, **kwargs) self.websocket = None # self.app = None self.websocket_timeout = websocket_timeout self.websocket_max_size = websocket_max_size self.websocket_max_queue = websocket_max_queue self.websocket_read_limit = websocket_read_limit self.websocket_write_limit = websocket_write_limit # timeouts make no sense for websocket routes def request_timeout_callback(self): if self.websocket is None: super().request_timeout_callback() def response_timeout_callback(self): if self.websocket is None: super().response_timeout_callback() def keep_alive_timeout_callback(self): if self.websocket is None: super().keep_alive_timeout_callback() def connection_lost(self, exc): if self.websocket is not None: self.websocket.connection_lost(exc) super().connection_lost(exc) def data_received(self, data): if self.websocket is not None: # pass the data to the websocket protocol self.websocket.data_received(data) else: try: super().data_received(data) except HttpParserUpgrade: # this is okay, it just indicates we've got an upgrade request pass def write_response(self, response): if self.websocket is not None: # websocket requests do not write a response self.transport.close() else: super().write_response(response) async def websocket_handshake(self, request, subprotocols=None): # let the websockets package do the handshake with the client headers = {} try: key = handshake.check_request(request.headers) handshake.build_response(headers, key) except InvalidHandshake: raise InvalidUsage("Invalid websocket request") subprotocol = None if subprotocols and "Sec-Websocket-Protocol" in request.headers: # select a subprotocol client_subprotocols = [ p.strip() for p in request.headers["Sec-Websocket-Protocol"].split(",") ] for p in client_subprotocols: if p in subprotocols: subprotocol = p headers["Sec-Websocket-Protocol"] = subprotocol break # write the 101 response back to the client rv = b"HTTP/1.1 101 Switching Protocols\r\n" for k, v in headers.items(): rv += k.encode("utf-8") + b": " + v.encode("utf-8") + b"\r\n" rv += b"\r\n" request.transport.write(rv) # hook up the websocket protocol self.websocket = WebSocketCommonProtocol( timeout=self.websocket_timeout, max_size=self.websocket_max_size, max_queue=self.websocket_max_queue, read_limit=self.websocket_read_limit, write_limit=self.websocket_write_limit, ) # Following two lines are required for websockets 8.x self.websocket.is_client = False self.websocket.side = "server" self.websocket.subprotocol = subprotocol self.websocket.connection_made(request.transport) self.websocket.connection_open() return self.websocket