I'm currently trying to integrate a websocket interface to my program. I'm using the https://websockets.readthedocs.io/en/stable/intro.html module for this purpose, along with asyncio. I'm currently struggling to implement the websocket functionalites in a dedicated class that sets up the websocket tasks to run in concurrency in the same event loop as the task running in MyDriver class.
main.py
from myDriver import MyDriver
from webSocketServer import WebSocketServer
async def main():
# loop = asyncio.get_event_loop()
driver = MyDriver()
ws = WebSocketServer()
await driver.drive()
# The following does not integrate properly with the above. The msgHandler is not ran
await websockets.serve(lambda websocket, path: ws.msgHandler(websocket, path), "localhost", 5678)
asyncio.run(main())
The lambda is here to get rid of the self argument coming from the class.
webSocketServer.py
import asyncio
import websockets
class WebSocketServer:
def __init__(self):
print('Init')
async def msgHandler(self, websocket, path):
self.sendTask = asyncio.create_task(self.sendHandler(websocket, path))
self.receiveTask = asyncio.create_task(self.receiveHandler(websocket, path))
await asyncio.wait([self.sendTask, self.receiveTask], return_when=asyncio.FIRST_COMPLETED)
async def sendHandler(self, websocket, path):
while True:
await asyncio.sleep(2)
message = producer()
await websocket.send(message)
async def receiveHandler(self, websocket, path):
async for message in websocket:
await self.printMsg()
async def printMsg(self, msg):
await asyncio.sleep(0.1)
print(msg)
def producer():
return 'Hi !'
I based my implementation on the examples provided on the websockets' Getting Started page. They use the loop.run_until_complete(server) & loop.run_forever() APIs. I also tried to use these by passing the loop in argument to the constructor of WebSocketServer(loop) and do the websockets.serve(lambda websocket, path: ws.msgHandler(websocket, path), "localhost", 5678) there, but then I get the error RuntimeError: This event loop is already running. I also had a look at loop.create_task(), which takes a coroutine as an argument.
Does anyone see a way I could properly integrate a websocket server running in the same event loop as my other task? Thx !