我用Tornado写一个Tcp服务器。 这是代码:
#! /usr/bin/env python
#coding=utf-8
from tornado.tcpserver import TCPServer
from tornado.ioloop import IOLoop
from tornado.gen import *
class TcpConnection(object):
def __init__(self,stream,address):
self._stream=stream
self._address=address
self._stream.set_close_callback(self.on_close)
self.send_messages()
def send_messages(self):
self.send_message(b'hello \n')
print("next")
self.read_message()
self.send_message(b'world \n')
self.read_message()
def read_message(self):
self._stream.read_until(b'\n',self.handle_message)
def handle_message(self,data):
print(data)
def send_message(self,data):
self._stream.write(data)
def on_close(self):
print("the monitored %d has left",self._address)
class MonitorServer(TCPServer):
def handle_stream(self,stream,address):
print("new connection",address,stream)
conn = TcpConnection(stream,address)
if __name__=='__main__':
print('server start .....')
server=MonitorServer()
server.listen(20000)
IOLoop.instance().start()
我面对一些错误assert self._read_callback is None, "Already reading"
,我想eorror是因为多个命令同时从套接字读取。然后我用tornado.gen.coroutine.here改变函数send_messages
是代码:
@gen.coroutine
def send_messages(self):
yield self.send_message(b'hello \n')
response1 = yield self.read_message()
print(response1)
yield self.send_message(b'world \n')
print((yield self.read_message()))
但还有其他一些错误。代码似乎在yield self.send_message(b'hello \n')
之后停止,并且以下代码似乎不会执行。
我该怎么办呢?如果你知道任何龙卷风tcpserver(不是HTTP!)代码与tornado.gen.coroutine,请告诉我。我会感激任何链接!
答案 0 :(得分:3)
send_messages()
使用send_message()
调用read_message()
和yield
,但这些方法不是协同程序,因此会引发异常。
您没有看到异常的原因是您调用了send_messages()
而没有让它出现,因此异常无处可去(垃圾收集器最终应该注意并打印异常,但这可能需要很长时间)。每当你调用一个协程时,你应该使用yield
等待它完成,或IOLoop.current().spawn_callback()
在"背景"中运行协同程序。 (这告诉Tornado你不打算产生协程,所以它会在它发生时立即打印出来)。此外,每当您覆盖一个方法时,您应该阅读文档以查看是否允许协程(当您覆盖TCPServer.handle_stream()
时,可以使其成为协程,但__init__()
可能不是协程。)
记录异常后,下一步就是修复它。您可以制作send_message()
和read_message()
协同程序(在此过程中删除handle_message()
回调),也可以使用tornado.gen.Task()
从协程中调用协同式代码。我一般建议到处使用协同程序。