Skip to content

Commit

Permalink
Fix loop not closing when client closes
Browse files Browse the repository at this point in the history
By using aiohttp's built-in async iterator, we can ensure the loop is
properly closed when the client is sending a close request.
  • Loading branch information
emlove committed Sep 11, 2020
1 parent fecf789 commit 576a61a
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 10 deletions.
9 changes: 2 additions & 7 deletions jsonrpc_websocket/jsonrpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,10 @@ async def _ws_loop(self):
"""Listen for messages from the websocket server."""
msg = None
try:
while True:
msg = await self._client.receive()

if msg.type == aiohttp.WSMsgType.CLOSED:
break
async for msg in self._client:
if msg.type == aiohttp.WSMsgType.ERROR:
break

if msg.type == aiohttp.WSMsgType.BINARY:
elif msg.type == aiohttp.WSMsgType.BINARY:
try:
# If we get a binary message, try and decode it as a
# UTF-8 JSON string, in case the server is sending
Expand Down
11 changes: 8 additions & 3 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from unittest.mock import Mock

import aiohttp
from aiohttp import ClientWebSocketResponse
import aiohttp.web
import pep8
import pytest
Expand Down Expand Up @@ -44,7 +45,7 @@ def receive(self, data):
def receive_binary(self, data):
self.test_server.test_binary(data)

class JsonTestServer():
class JsonTestServer(ClientWebSocketResponse):
def __init__(self, loop=None):
self.loop = loop
self.send_handler = None
Expand All @@ -65,7 +66,7 @@ def test_error(self):
self.receive_queue.put_nowait(aiohttp.WSMessage(aiohttp.WSMsgType.ERROR, 0, ''))

def test_close(self):
self.receive_queue.put_nowait(aiohttp.WSMessage(aiohttp.WSMsgType.CLOSED, 0, ''))
self.receive_queue.put_nowait(aiohttp.WSMessage(aiohttp.WSMsgType.CLOSED, None, None))

def test_ping(self):
self.receive_queue.put_nowait(aiohttp.WSMessage(aiohttp.WSMsgType.PING, 0, ''))
Expand All @@ -79,7 +80,7 @@ async def receive(self):
async def close(self):
if not self._closed:
self._closed = True
self.receive_queue.put_nowait(aiohttp.WSMessage(aiohttp.WSMsgType.CLOSED, 0, ''))
self.receive_queue.put_nowait(aiohttp.WSMessage(aiohttp.WSMsgType.CLOSING, None, None))


def assertSameJSON(json1, json2):
Expand Down Expand Up @@ -144,7 +145,11 @@ def handler(server, data):
assert isinstance(transport_error.value.args[1], asyncio.TimeoutError)

async def test_client_closed(server):
assert server.session.run_loop_future.done() is False
await server.close()
assert server.session.run_loop_future.done() is False
await server.session.run_loop_future
assert server.session.run_loop_future.done() is True
with pytest.raises(TransportError, match='Client is not connected.'):
def handler(server, data):
pass
Expand Down

0 comments on commit 576a61a

Please sign in to comment.