import asyncioimport itertools
async def websocket_handler(request):
ws = web.WebSocketResponse() await ws.prepare(request)
for i in itertools.count(): if ws.closed: break await asyncio.sleep(1) message = "hello_" + str(i) print(f"sending: {message}") await ws.send_str(message) print(f"sent: {message}")
print('websocket connection closed')
return ws
app = web.Application()app.router.add_get('/ws', websocket_handler)web.run_app(app, host="127.0.0.1", port=8080)
# wsclient.py
# Just prints out the messages, and attempts to close the connection when it receives a message with content "hello_5"
import asyncioimport aiohttp
async def main(): session = aiohttp.ClientSession() async with session.ws_connect('http://localhost:8080/ws') as ws:
async for msg in ws: if msg.type == aiohttp.WSMsgType.TEXT: if msg.data == 'hello_5': print("closing") await ws.close() break else: print(msg.data) elif msg.type == aiohttp.WSMsgType.CLOSED: break elif msg.type == aiohttp.WSMsgType.ERROR: break
loop = asyncio.get_event_loop()# Blocking call which returns when the hello_world() coroutine is doneloop.run_until_complete(main())loop.close()
$ python server.py ======== Running on http://127.0.0.1:8080 ========(Press CTRL+C to quit)sending: hello_0sent: hello_0sending: hello_1sent: hello_1sending: hello_2sent: hello_2sending: hello_3sent: hello_3sending: hello_4sent: hello_4sending: hello_5sent: hello_5sending: hello_6sent: hello_6sending: hello_7sent: hello_7
$ python wsclient.py hello_0hello_1hello_2hello_3hello_4closing
$ python wsclient.py hello_0hello_1hello_2hello_3hello_4closingUnclosed client sessionclient_session: <aiohttp.client.ClientSession object at 0x7f54cf840e80>
--
You received this message because you are subscribed to the Google Groups "aio-libs" group.
To unsubscribe from this group and stop receiving emails from it, send an email to aio-libs+u...@googlegroups.com.
To post to this group, send email to aio-...@googlegroups.com.
Visit this group at https://groups.google.com/group/aio-libs.
To view this discussion on the web visit https://groups.google.com/d/msgid/aio-libs/0e126288-3433-435c-ac6a-a3a479b52649%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
# server.py
import aiohttp
from aiohttp import web
import asyncioimport itertools
async def websocket_handler(request):
ws = web.WebSocketResponse() await ws.prepare(request)
incoming = asyncio.ensure_future(process_incoming_messages(ws))
for i in itertools.count(): if ws.closed: break await asyncio.sleep(1) message = "hello_" + str(i) print(f"sending: {message}") await ws.send_str(message) print(f"sent: {message}")
print('websocket connection closed')
await incoming
return ws
async def process_incoming_messages(ws):
async for msg in ws:
pass
app = web.Application()app.router.add_get('/ws', websocket_handler)web.run_app(app, host="127.0.0.1", port=8080)
$ python server.py ======== Running on http://127.0.0.1:8080 ========(Press CTRL+C to quit)sending: hello_0sent: hello_0sending: hello_1sent: hello_1sending: hello_2sent: hello_2sending: hello_3sent: hello_3sending: hello_4sent: hello_4sending: hello_5sent: hello_5
$ python wsclient.py hello_0hello_1hello_2hello_3hello_4closingUnclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7f47eb443e80>
# server.py
import aiohttpfrom aiohttp import web
import asyncioimport itertools
async def websocket_handler(request):
ws = web.WebSocketResponse() await ws.prepare(request)
incoming = asyncio.ensure_future(process_incoming_messages(ws))
try:
for i in itertools.count(): if ws.closed: break await asyncio.sleep(1) message = "hello_" + str(i) print(f"sending: {message}") await ws.send_str(message) print(f"sent: {message}")
except Exception as e: print(e.__class__)
print('websocket connection closed')
await incoming
return ws
async def process_incoming_messages(ws): async for msg in ws: pass
app = web.Application()app.router.add_get('/ws', websocket_handler)web.run_app(app, host="127.0.0.1", port=8080)
$ python server.py ======== Running on http://127.0.0.1:8080 ========(Press CTRL+C to quit)sending: hello_0sent: hello_0sending: hello_1sent: hello_1sending: hello_2sent: hello_2sending: hello_3sent: hello_3sending: hello_4sent: hello_4sending: hello_5sent: hello_5
<class 'concurrent.futures._base.CancelledError'>websocket connection closed
$ python wsclient.py hello_0hello_1hello_2hello_3hello_4closingUnclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7f8960aa8e80>
--
You received this message because you are subscribed to the Google Groups "aio-libs" group.
To unsubscribe from this group and stop receiving emails from it, send an email to aio-libs+u...@googlegroups.com.
To post to this group, send email to aio-...@googlegroups.com.
Visit this group at https://groups.google.com/group/aio-libs.
To view this discussion on the web visit https://groups.google.com/d/msgid/aio-libs/2310e492-b4db-4672-a814-1f8320d2c3e9%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
$ python wsclient.py hello_0hello_1hello_2hello_3hello_4closingUnclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7f2f49e22e10>
To view this discussion on the web visit https://groups.google.com/d/msgid/aio-libs/f2a666ed-049e-4d0a-8f40-0ad564dfc43a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
session = aiohttp.ClientSession()async with session.ws_connect('http://example.org/ws') as ws:
async for msg in ws:
if msg.type == aiohttp.WSMsgType.TEXT: if msg.data == 'close cmd': await ws.close() break else: await ws.send_str(msg.data + '/answer')
elif msg.type == aiohttp.WSMsgType.CLOSED: break elif msg.type == aiohttp.WSMsgType.ERROR: break
In my code I normally use this pattern, seems to work well in my limited testing (but the code is not yet in production so, caveat emptor):async def websocket_handler(request):ws = web.WebSocketResponse()await ws.prepare(request)try:async for msg in ws:...do stuff with incoming messagesfinally:await asyncio.shield(cleanup_code())Where cleanup_code() is whatever code you need to run after the websocket disconnects. I have found (by trial and error) that the task was being cancelled sometimes while cleanup_code() was still yet to complete, and so the asyncio.shield() was needed.