Skip to content

Instantly share code, notes, and snippets.

@athoune
Created January 7, 2018 21:57
Show Gist options
  • Save athoune/f425aed8645c0a1e485c12f1ad87c339 to your computer and use it in GitHub Desktop.
Save athoune/f425aed8645c0a1e485c12f1ad87c339 to your computer and use it in GitHub Desktop.
jsonrpc2 with aiohttp
import logging
from jsonrpc.jsonrpc2 import JSONRPC20Request
def jsonrpcrequest(data):
logging.debug(data)
if isinstance(data, list):
for d in data:
yield JSONRPC20Request.from_data(d)
else:
if data is not None:
yield JSONRPC20Request.from_data(data)
class Session:
def __init__(self, ws):
self.ids = set()
self.ws = ws
self.queue = list()
def __aiter__(self):
return self
async def __anext__(self):
while len(self.queue) == 0:
msg = None
try:
msg = await self.ws.receive_json()
except TypeError:
continue
except RuntimeError as e:
if e.args[0] == 'WebSocket connection is closed.':
raise StopAsyncIteration
raise e
finally:
logging.debug(msg)
for req in jsonrpcrequest(msg):
self.queue.append(req)
req = self.queue.pop()
_id = req._id
if _id in self.ids:
raise Exception("Replayed id")
self.ids.add(_id)
return req
@athoune
Copy link
Author

athoune commented Jan 7, 2018

async def jsonrpc_handler(request):
    logging.debug('Websocket connection starting')
    ws = web.WebSocketResponse()
    await ws.prepare(request)
    logging.debug('Websocket connection ready')

    session = Session(ws)

    async for req in session:
        assert req.method == "run"
        await run(request.app['conn'], ws, req)

    logging.debug('Websocket connection closed')
    return ws

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment