zeromq plus json

We’ll use ZeroMQ to take JSON-RPC requests, and process them asynchronously. (The synchronous version is here.) The server should respond to “ping” with “pong”.

Install aiozmq to take requests and jsonrpcserver to process them:

$ pip install aiozmq jsonrpcserver

Create a server.py:

import asyncio
import aiozmq
import zmq
from jsonrpcserver.aio import methods
from jsonrpcserver.response import NotificationResponse

@methods.add
async def ping():
    return 'pong'

async def main():
    rep = await aiozmq.create_zmq_stream(zmq.REP, bind='tcp://*:5000')
    while True:
        request = await rep.read()
        response = await methods.dispatch(request[0].decode())
        if not response.is_notification:
            rep.write((str(response).encode(),))

if __name__ == '__main__':
    asyncio.set_event_loop_policy(aiozmq.ZmqEventLoopPolicy())
    asyncio.get_event_loop().run_until_complete(main())

Start the server:

$ python server.py

Synchronous Client

Use jsonrpcclient to send requests:

$ pip install 'jsonrpcclient[pyzmq]'
$ python
>>> from jsonrpcclient.zeromq_client import ZeroMQClient
>>> ZeroMQClient('tcp://localhost:5000').request('ping')
--> {"jsonrpc": "2.0", "method": "ping", "id": 1}
<-- {"jsonrpc": "2.0", "result": "pong", "id": 1}
'pong'

Asynchronous Client

$ pip install 'jsonrpcclient[pyzmq]'

Create a client.py:

import asyncio
import zmq
from jsonrpcclient.zeromq_async_client import ZeroMQAsyncClient

async def main():
    client = ZeroMQAsyncClient('tcp://localhost:5000')
    response = await client.request('ping')
    print(response)

asyncio.set_event_loop(zmq.asyncio.ZMQEventLoop())
asyncio.get_event_loop().run_until_complete(main())
$ python client.py
--> {"jsonrpc": "2.0", "method": "ping", "id": 1}
<-- {"jsonrpc": "2.0", "result": "pong", "id": 1}
'pong'