def wsproto_demo(host, port): ''' Demonstrate wsproto: 0) Open TCP connection 1) Negotiate WebSocket opening handshake 2) Send a message and display response 3) Send ping and display pong 4) Negotiate WebSocket closing handshake :param stream: a socket stream ''' # 0) Open TCP connection print('Connecting to {}:{}'.format(host, port)) conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) conn.connect((host, port)) # 1) Negotiate WebSocket opening handshake print('Opening WebSocket') ws = WSConnection(ConnectionType.CLIENT, host=host, resource='server') # events is a generator that yields websocket event objects. Usually you # would say `for event in ws.events()`, but the synchronous nature of this # client requires us to use next(event) instead so that we can interleave # the network I/O. It will raise StopIteration when it runs out of events # (i.e. needs more network data), but since this script is synchronous, we # will explicitly resume the generator whenever we have new network data. events = ws.events() # Because this is a client WebSocket, wsproto has automatically queued up # a handshake, and we need to send it and wait for a response. net_send_recv(ws, conn) event = next(events) if isinstance(event, ConnectionEstablished): print('WebSocket negotiation complete') else: raise Exception('Expected ConnectionEstablished event!') # 2) Send a message and display response message = "wsproto is great" print('Sending message: {}'.format(message)) ws.send_data(message) net_send_recv(ws, conn) event = next(events) if isinstance(event, TextReceived): print('Received message: {}'.format(event.data)) else: raise Exception('Expected TextReceived event!') # 3) Send ping and display pong payload = b"table tennis" print('Sending ping: {}'.format(payload)) ws.ping(payload) net_send_recv(ws, conn) event = next(events) if isinstance(event, PongReceived): print('Received pong: {}'.format(event.payload)) else: raise Exception('Expected PongReceived event!') # 4) Negotiate WebSocket closing handshake print('Closing WebSocket') ws.close(code=1000, reason='sample reason') # After sending the closing frame, we won't get any more events. The server # should send a reply and then close the connection, so we need to receive # twice: net_send_recv(ws, conn) conn.shutdown(socket.SHUT_WR) net_recv(ws, conn)
async def wsproto_client_demo(host, port, use_ssl): ''' Demonstrate wsproto: 0) Open TCP connection 1) Negotiate WebSocket opening handshake 2) Send a message and display response 3) Send ping and display pong 4) Negotiate WebSocket closing handshake :param stream: a socket stream ''' # 0) Open TCP connection print('[C] Connecting to {}:{}'.format(host, port)) conn = await trio.open_tcp_stream(host, port) if use_ssl: conn = upgrade_stream_to_ssl(conn, host) # 1) Negotiate WebSocket opening handshake print('[C] Opening WebSocket') ws = WSConnection(ConnectionType.CLIENT, host=host, resource='server') events = ws.events() # Because this is a client WebSocket, wsproto has automatically queued up # a handshake, and we need to send it and wait for a response. await net_send_recv(ws, conn) event = next(events) if isinstance(event, ConnectionEstablished): print('[C] WebSocket negotiation complete') else: raise Exception(f'Expected ConnectionEstablished event! Got: {event}') # 2) Send a message and display response message = "wsproto is great" * 10 print('[C] Sending message: {}'.format(message)) ws.send_data(message) await net_send_recv(ws, conn) event = next(events) if isinstance(event, TextReceived): print('[C] Received message: {}'.format(event.data)) else: raise Exception(f'Expected TextReceived event! Got: {event}') # 3) Send ping and display pong payload = b"table tennis" print('[C] Sending ping: {}'.format(payload)) ws.ping(payload) await net_send_recv(ws, conn) event = next(events) if isinstance(event, PongReceived): print('[C] Received pong: {}'.format(event.payload)) else: raise Exception(f'Expected PongReceived event! Got: {event}') # 4) Negotiate WebSocket closing handshake print('[C] Closing WebSocket') ws.close(code=1000, reason='sample reason') # After sending the closing frame, we won't get any more events. The server # should send a reply and then close the connection, so we need to receive # twice: await net_send_recv(ws, conn) await conn.aclose()