我借用了这个简单聊天的代码:
import tornado.ioloop
import tornado.web
import tornado.websocket
import tornado.gen
clients = []
class IndexHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
def get(request):
request.render("index.html")
class WebSocketChatHandler(tornado.websocket.WebSocketHandler):
def open(self, *args):
print("open", "WebSocketChatHandler")
clients.append(self)
def check_origin(self, origin):
return True
@tornado.gen.coroutine
def on_message(self, message):
for client in clients:
client.write_message(message)
@tornado.gen.coroutine
def myroutine(m):
print "mensaje: "
c = (yield 123123123)
print ("mensaje", m, c)
yield myroutine(message)
def on_close(self):
clients.remove(self)
app = tornado.web.Application([(r'/chat', WebSocketChatHandler), (r'/', IndexHandler)])
app.listen(8888)
tornado.ioloop.IOLoop.instance().start()
聊天应用程序运行良好(即,我使用websocket客户端看到回声),我对其进行了一些修改,以测试一些自定义代码。你知道吗
而且,为了测试的目的,我想插入一个可能很重的函数调用,我想让它异步。你知道吗
这里的实际意图是myroutine
将启动一个游戏引擎作为并行任务。你知道吗
也许我遗漏了一些东西,但是我的代码中的意图是将腐蚀分为两部分重新安排。这意味着:corroutine应该打印“message”,然后产生值123123(实际上,这是一个立即值,它将被包装到一个已经解析的未来中-该值将在结果中),从而将自己重新安排到下一次迭代,并且(在后一次迭代中)打印给定的元组("message", message, c)
。你知道吗
我的问题是,该功能从未被重新安排(即,控制台只打印“message:”。你知道吗
我做错什么了?这是我第一次尝试Tornado(以及一般的异步编程)。我怎么能告诉龙卷风循环类似“哥们,这个值是我的腐蚀性,这些是我腐蚀性的论点。请把它安排在下一个循环中并行地开始?你知道吗
存在两个问题:首先,您不能从一个协程中产生所有类型的对象,您必须产生一个Future或其他特殊的可屈服对象。所以当你的协同进程产生123123的收益时,Tornado抛出了一个“坏收益”异常。不幸的是,Tornado的websocket代码并不是为了捕获来自“on\u message”的异常而构建的,如果“on\u message”是一个协程,那么异常将以静默方式传递。见the warning at the bottom of the coroutine documentation。你知道吗
您的解决方案是从“mycoroutine”生成一个有效的对象。如果你只是想屈服一下,yield "gen.moment":
如果您想让“mycoroutine”并行运行,而不是阻塞“on\u message”,只需调用它而不产生:
但是!以这种方式调用协同程序意味着没有人在监听它是否抛出异常。确保捕获并记录“mycoroutine”中的所有异常,否则它们将以静默方式传递。你知道吗
相关问题 更多 >
编程相关推荐