Skip to content

Commit 51ad398

Browse files
authored
Merge pull request #55 from HyperionGray/example_client_handle_close_v2
Example client exits on ConnectionClosed (#22)
2 parents a75c4d6 + e971e7b commit 51ad398

File tree

1 file changed

+38
-25
lines changed

1 file changed

+38
-25
lines changed

examples/client.py

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818

1919
logging.basicConfig(level=logging.DEBUG)
20-
logger = logging.getLogger()
2120
here = pathlib.Path(__file__).parent
2221

2322

@@ -27,7 +26,6 @@ def commands():
2726
print('send <MESSAGE> -> send message')
2827
print('ping <PAYLOAD> -> send ping with payload')
2928
print('close [<REASON>] -> politely close connection with optional reason')
30-
print('[ctrl+D] -> rudely close connection')
3129
print()
3230

3331

@@ -55,39 +53,54 @@ async def main(args):
5553
try:
5654
logging.debug('Connecting to WebSocket…')
5755
async with open_websocket_url(args.url, ssl_context) as conn:
58-
logging.debug('Connected!')
5956
await handle_connection(conn)
60-
logging.debug('Connection closed')
6157
except OSError as ose:
6258
logging.error('Connection attempt failed: %s', ose)
6359
return False
6460

6561

66-
async def handle_connection(connection):
62+
async def handle_connection(ws):
6763
''' Handle the connection. '''
64+
logging.debug('Connected!')
65+
try:
66+
async with trio.open_nursery() as nursery:
67+
nursery.start_soon(get_commands, ws)
68+
nursery.start_soon(get_messages, ws)
69+
except ConnectionClosed as cc:
70+
reason = '<no reason>' if cc.reason.reason is None else '"{}"'.format(
71+
cc.reason.reason)
72+
print('Closed: {}/{} {}'.format(cc.reason.code, cc.reason.name, reason))
73+
74+
75+
async def get_commands(ws):
76+
''' In a loop: get a command from the user and execute it. '''
6877
while True:
69-
try:
70-
logger.debug('top of loop')
71-
await trio.sleep(0.1) # allow time for connection logging
72-
cmd = await trio.run_sync_in_worker_thread(input, 'cmd> ',
73-
cancellable=True)
74-
if cmd.startswith('ping '):
75-
await connection.ping(cmd[5:].encode('utf8'))
76-
elif cmd.startswith('send '):
77-
await connection.send_message(cmd[5:])
78-
message = await connection.get_message()
79-
print('response> {}'.format(message))
80-
elif cmd.startswith('close'):
81-
try:
82-
reason = cmd[6:]
83-
except IndexError:
84-
reason = None
85-
await connection.aclose(code=1000, reason=reason)
86-
break
78+
cmd = await trio.run_sync_in_worker_thread(input, 'cmd> ',
79+
cancellable=True)
80+
if cmd.startswith('ping'):
81+
payload = cmd[5:].encode('utf8') or None
82+
await ws.ping(payload)
83+
elif cmd.startswith('send'):
84+
message = cmd[5:] or None
85+
if message is None:
86+
logging.error('The "send" command requires a message.')
8787
else:
88-
commands()
89-
except ConnectionClosed:
88+
await ws.send_message(message)
89+
elif cmd.startswith('close'):
90+
reason = cmd[6:] or None
91+
await ws.aclose(code=1000, reason=reason)
9092
break
93+
else:
94+
commands()
95+
# Allow time to receive response and log print logs:
96+
await trio.sleep(0.25)
97+
98+
99+
async def get_messages(ws):
100+
''' In a loop: get a WebSocket message and print it out. '''
101+
while True:
102+
message = await ws.get_message()
103+
print('message: {}'.format(message))
91104

92105

93106
if __name__ == '__main__':

0 commit comments

Comments
 (0)