我计划写一个包装websockets包的类WebsocketHandler
这是代码:
import asyncio
import websockets
class WebsocketHandler:
__connection = None
def __init__(self):
asyncio.run(self.__setConnection())
async def __setConnection(self):
async with websockets.connect("ws://localhost/your/path") as websocket:
self.__connection = websocket
print("Connected")
def send(self, msg):
self.__connection.send(msg)
print("message Send")
ws = WebsocketHandler()
ws.send("message")
对于服务器部分,我还有另一个完成的脚本可以工作(已用其他语言的其他脚本进行了测试),当我建立新的连接,收到消息以及与客户端断开连接时,该消息会向我发送消息。
尝试时,脚本成功连接到我的websocket服务器(脚本打印Connected
,在服务器端,我得到了一个新连接)。
然后我在脚本中得到警告
RuntimeWarning: coroutine 'WebSocketCommonProtocol.send' was never awaited
self.__connection.send(msg)
然后我的脚本打印Message send
,它停止了。
问题在于,在服务器端,我没有收到消息的事实,而只有一个告诉我客户端断开连接的消息。基本上,脚本不会发送消息,也不会产生错误。
任何人都知道问题出在哪里吗?
答案 0 :(得分:2)
问题是WebsocketHandler
类只有一个异步方法,即__setConnection
,该方法通过调用asyncio.run
函数来运行。 docs说
此函数始终创建一个新的事件循环,并在事件循环中将其关闭 结束。
也就是说,这是唯一可以运行异步代码的地方。您的代码会创建一个websocket连接,并在打印“已连接”后立即关闭它。发生这种情况是因为您使用websockets.connect
作为异步上下文管理器调用了async with
方法,该方法在退出时自动关闭了连接。这是第一个缺陷,第二个缺陷是self.__connection.send
函数是一个协程,并且直到您等待之前它都不会运行。这正是错误消息告诉您的内容。这是修复websocket处理程序类的方法:
import asyncio
import websockets
class WebsocketHandler(object):
def __init__(self):
self.conn = None
async def connect(self, url):
self.conn = await websockets.connect(url)
async def send(self, msg):
await self.conn.send(msg)
async def close(self):
await self.conn.close()
async def main():
handler = WebsocketHandler()
await handler.connect('ws://localhost:8765')
await handler.send('hello')
await handler.send('world')
await handler.close()
loop = asyncio.get_event_loop()
loop.run_until_complete(main())