I started to implement a websocket client via Websockets, this is working however I am not satisfied yet and I am strugleling to know what are the good practice. Please find below the current code. I subscribe to two different channels:
-> block_timestamp: Get timestamps that are pushed around each 2sec
-> mint_start: Get a timesteamp that is pushed only once
Those data are managed via on_message function and as soon as: mint_start >= block_timestamp, it should execute an external function.
async def event_listener(id, params, queue):
async with websockets.connect(url) as ws:
await ws.send(json.dumps({"id": 1, "method": "eth_subscribe", "params": params}))
subscription_response = await ws.recv()
subscription_response = json.loads(subscription_response)
if subscription_response.get("error"):
return subscription_response["error"]["code"], subscription_response["error"]["message"]
else:
print(f"Subscribed with success to stream id: {subscription_response['result']}")
while True:
message = await ws.recv()
print(message)
await queue.put((id, message))
async def on_message(queue):
block_timestamp, start_mint = None, None
a = True
while a:
id, value = await queue.get()
print(id, value)
if id == "block_timestamp":
block_timestamp = (json.loads(value)['params']['result']["timestamp"])
else:
start_mint = (decode_single('(uint112,uint112)', bytearray.fromhex(value['params']['result']['data'][2:])))
if block_timestamp is not None:
#execute a function
async def main():
params1 = ["newHeads"]
params2 = ["logs", {"address": ["0xf4003f4efbe8691b60249e6afbd307abe7758adb"],
"topics": [Web3.keccak(text="Sync(uint112,uint112)").hex()]}]
queue = asyncio.Queue()
await asyncio.gather(
event_listener("block_timestamp", params1, queue),
event_listener("mint_start", params2, queue),
on_message(queue)
)
if __name__ == "__main__":
asyncio.run(main())
According to me, when this code is is executed, two connections are made to the websockets. So this is not good, as only one connection is necessary.How could I manage this connection to be done only once ?
In addition, I would like to auto-reconnect automatically in case the connected stop. Would you have an idea of how it can be done properly ?
To finish, when the condition is meet (mint_start >= block_timestamp), the code will execute an external function. I would also like to stop the websocket connection and also the tasks running. But I have trouble to manage it correctly via asyncio.
A bit of help would be much appreaciated ! Thanks