我目前正在尝试将websocket界面集成到我的程序中。为此,我正在使用https://websockets.readthedocs.io/en/stable/intro.html模块以及asyncio。我目前正在努力在专用类中实现websocket功能,该类将websocket任务设置为在与MyDriver类中运行的任务相同的事件循环中并发运行。
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())
这里的lambda摆脱了来自类的自我争论。
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 !'
我的实现基于websockets入门页面上提供的示例。他们使用loop.run_until_complete(server)
&loop.run_forever()
API。我还尝试通过将loop
in参数传递给的构造函数来使用它们,WebSocketServer(loop)
并在websockets.serve(lambda websocket, path: ws.msgHandler(websocket, path), "localhost", 5678)
那里进行操作,但随后出现错误RuntimeError: This event loop is already running
。我还查看了loop.create_task()
,其中将协程作为参数。
有没有人看到我可以正确集成与我的其他任务在同一事件循环中运行的websocket服务器的方法?谢谢 !
他们使用
loop.run_until_complete(server)
&loop.run_forever()
API。
最好将它们转换为asyncio.run()
,这是启动异步代码的更健壮的方法。只是您的转换不完整,缺少了run_forever()
一部分。run_forever()
之所以需要这样的东西,是因为websockets.serve()
它并不意味着“完成后提供服务并退出”,而是意味着“开始提供服务并向服务器返回一个句柄”。该句柄将立即(几乎)返回,并且如果您从那时返回main
,如您的代码那样,程序将在处理单个连接之前退出。
您需要做的是在main的末尾添加另一个等待,只要程序需要运行,您就可以在其中等待。一种方法是to await asyncio.Event().wait()
,它将永远等待,并且与await等效loop.run_forever()
。而且由于可以使用服务器对象,因此wait_closed()
只要服务器正在运行(即协程有意通过调用来将server.close()
其关闭),就可以使用其方法来等待,这可能就是您想要的。
换句话说,您需要将的最后一行修改main()
为:
server = await websockets.serve(lambda websocket, path: ws.msgHandler(websocket, path), "localhost", 5678)
await server.wait_closed()
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句