python - 为什么我不能在协程调用的协程中发送 websocket?

标签 python websocket python-asyncio

为什么:

async def setup():
    async with websockets.connect('ws:/ip.address:port') as ws:
        await ws.send('TEST MESSAGE')

def startup():
    loop = asyncio.new_event_loop() # because it's running in a thread
    asyncio.set_event_loop(loop)
    asyncio.ensure_future(setup())
    loop.run_forever()

通过 websocket 发送消息并且:

async def setup():
    async with websockets.connect('ws:/ip.address:port') as ws:
        loop = asyncio.get_event_loop()
        loop.create_task(send_messages(ws))

async def send_messages(ws):
    await ws.send('TEST MESSAGE')

def startup():
    loop = asyncio.new_event_loop() # because it's running in a thread
    asyncio.set_event_loop(loop)
    asyncio.ensure_future(setup())
    loop.run_forever()

不是吗?

我已经从我的代码中删除了代码以简化它 - 如果需要可以发布原始代码。第二个版本似乎卡在等待 ws.send('test')部分来自打开日志记录、调试等。

我想知道将 websocket 连接作为参数传递是否存在问题。如果您记录传递的内容和接收的内容,它们都会返回 <websockets.client.WebSocketClientProtocol object at 0x04B51A90>两次使用相同的地址。

我最终想要做的事情,以及即使问题无法回答也欢迎如何做到这一点的建议是:

有两个协程运行,几乎永远这样: * 从 tkinter GUI 中的常规函数​​放置的队列中获取消息并将它们发送到 websocket * 从 websocket 获取消息并在 GUI 中更改内容

我认为 websockets 库作为 asyncio 将是实现此目的的方法,但我愿意接受任何建议。

编辑:忘记添加错误消息!

2017-03-19 10:49:31,103 ERROR asyncio Task exception was never retrieved
future: <Task finished coro=<send_messages() done, defined at chessboard.py:74> exception=ConnectionClosed('WebSocket connection is closed: code = 1000, no reason.',) created at chessboard.py:103>
source_traceback: Object created at (most recent call last):
  File "C:\Program Files (x86)\Python35-32\lib\threading.py", line 882, in _bootstrap
    self._bootstrap_inner()
  File "C:\Program Files (x86)\Python35-32\lib\threading.py", line 914, in _bootstrap_inner
    self.run()
  File "C:\Program Files (x86)\Python35-32\lib\threading.py", line 862, in run
    self._target(*self._args, **self._kwargs)
  File "chessboard.py", line 120, in startup
    loop.run_forever()
  File "C:\Program Files (x86)\Python35-32\lib\asyncio\base_events.py", line 345, in run_forever
    self._run_once()
  File "C:\Program Files (x86)\Python35-32\lib\asyncio\base_events.py", line 1312, in _run_once
    handle._run()
  File "C:\Program Files (x86)\Python35-32\lib\asyncio\events.py", line 125, in _run
    self._callback(*self._args)
  File "C:\Program Files (x86)\Python35-32\lib\asyncio\tasks.py", line 307, in _wakeup
    self._step()
  File "C:\Program Files (x86)\Python35-32\lib\asyncio\tasks.py", line 239, in _step
    result = coro.send(None)
  File "chessboard.py", line 103, in setup
    loop.create_task(send_messages(ws))
Traceback (most recent call last):
  File "C:\Program Files (x86)\Python35-32\lib\asyncio\tasks.py", line 239, in _step
    result = coro.send(None)
  File "C:\Program Files (x86)\Python35-32\lib\asyncio\coroutines.py", line 121, in send
    return self.gen.send(value)
  File "chessboard.py", line 81, in send_messages
    await ws.send(str(message))#seems to be stopping here - why isn't it sending?
  File "C:\Program Files (x86)\Python35-32\lib\site-packages\websockets\protocol.py", line 309, in send
    yield from self.ensure_open()
  File "C:\Program Files (x86)\Python35-32\lib\site-packages\websockets\protocol.py", line 401, in ensure_open
    raise ConnectionClosed(self.close_code, self.close_reason)
websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1000, no reason.

最佳答案

可以将 websocket 作为参数传递。这里的问题是,当等待 send 协程时,websocket 连接已经关闭(如错误消息中所述)。发生这种情况是因为连接上下文在 send_messages 任务发送消息之前完成。

相反,请考虑这个工作示例:

async def main():
    async with websockets.connect('ws:/ip.address:port') as ws:
        await send_messages(ws)

async def send_messages(ws):
    await ws.send('TEST MESSAGE')


loop = asyncio.get_event_loop()
loop.run_until_complete(main)

关于python - 为什么我不能在协程调用的协程中发送 websocket?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42885563/

相关文章:

python - 我收到此错误 : "ImportError: cannot import name python" How do I fix it?

python - asyncio websocket 无前缀发送

javascript - websocket php 与 Node js

kotlin - Kotlin 中的 Websocket 客户端

python - 无法以“w”模式写入文件(IOError : [Errno 2] No such file or directory: 'items.csv' )

python - 将服务器目录树内的 html 文件加载到 iframe 失败

python-3.x - Asyncio Queue 等待直到它已满,然后才会返回某些内容

mongodb - 为什么 MongoDB 的 python motor 客户端在用 starlette 运行时比 pymongo 慢很多?

python - 如何使用 pathlib.Path().glob() 读入文件并将具有相同文件名的文件输出到另一个子文件夹

python - 如何增加Python异步循环警告的阈值时间?