【问题标题】:async with Tornado TCPClient and TCPServer与 Tornado TCPClient 和 TCPServer 异步
【发布时间】:2016-12-05 19:46:04
【问题描述】:

我无法让 TCPClient 和 TCPServer 进入 Tornado。

我有以下服务器代码:

from tornado import gen
from tornado.ioloop import IOLoop
from tornado.iostream import IOStream, StreamClosedError
from tornado.tcpclient import TCPClient
from tornado.tcpserver import TCPServer
from tornado.platform.asyncio import to_tornado_future, to_asyncio_future


class MyServer(TCPServer):

    async def handle_stream(self, stream, address):
        try:
            while True:
               encoded="***".encode()
               msg= await stream.read_until(encoded)
               print(msg)

        except StreamClosedError:
            print("connection error")

server = MyServer()
server.listen(10000)
IOLoop.current().start()

以及以下客户端代码:

from tornado import gen
from tornado.ioloop import IOLoop
from tornado.iostream import IOStream, StreamClosedError
from tornado.tcpclient import TCPClient
from tornado.platform.asyncio import to_tornado_future, to_asyncio_future
tcp_client = TCPClient()


async def client():
    while True:
        try:
            stream = await  tcp_client.connect('localhost', 10000)

            # Set TCP_NODELAY / disable Nagle's Algorithm.
            stream.set_nodelay(True)

            while True:
                msg ="hello ***"
                await  stream.write(msg.encode())
                await gen.sleep(5)

        except StreamClosedError as exc:
            print("error connecting")

loop = IOLoop.current()
loop.spawn_callback(client)
loop.start()

我一直在服务器端收到一个警告,提示从未等待过 handle_stream:

/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/tornado-4.4.2-py3.5-macosx-10.6-intel.egg/tornado/netutil.py:272: RuntimeWarning: coroutine 'MyServer.handle_stream' was never awaited
  callback(connection, address)
ERROR:tornado.application:Error in connection callback
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/tornado-4.4.2-py3.5-macosx-10.6-intel.egg/tornado/tcpserver.py", line 276, in _handle_connection
    self.io_loop.add_future(future, lambda f: f.result())
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/tornado-4.4.2-py3.5-macosx-10.6-intel.egg/tornado/ioloop.py", line 593, in add_future

谁能告诉我我做错了什么以及如何使用 async 和 await 让它工作。

这与杰西友好回答的以下问题有关:

Tornado TCP Server / Client process communication

我试图让他的代码与 async 和 await 一起工作,但是遇到了同样的问题....如果我将上面的代码更改为使用 yield 和 coroutines 它可以工作...

【问题讨论】:

  • Tornado 的哪个版本? TCPServer.handle_stream 直到 4.2 版本才允许成为协程。
  • 嗨 Ben 我正在运行最新版本的 tornado-4.4.2。我添加了我刚刚得到的异常......

标签: tornado


【解决方案1】:

我看到了问题,将在此处修复:github.com/tornadoweb/tornado/pull/1906 同时我认为handle_stream 不能是本机协程,至少不是以任何方便的方式。

【讨论】:

  • 嗨,杰西,我希望你一切都好。我还能使用旧式@co-routine 吗?这似乎工作。我打算使用 to_asyncio_future() 并入 async 并等待,但现在的解决方法不太理想……使用您的 github pull 这如何工作?我现在可以下载你的补丁版本还是需要等待下一个龙卷风版本?
  • 当然,现在使用@gen.coroutine,性能会受到轻微影响,但肯定是正确的。
  • 如果您从 Github master 安装 Tornado,则该拉取请求现在已合并,您可以为 handle_stream 使用协程:github.com/tornadoweb/tornado/pull/1906
猜你喜欢
  • 2015-11-05
  • 1970-01-01
  • 2017-08-20
  • 1970-01-01
  • 1970-01-01
  • 2012-08-12
  • 2014-07-29
  • 1970-01-01
  • 2012-05-20
相关资源
最近更新 更多