为以后的循环迭代安排腐蚀程序

2024-10-02 16:32:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我借用了这个简单聊天的代码:

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(以及一般的异步编程)。我怎么能告诉龙卷风循环类似“哥们,这个值是我的腐蚀性,这些是我腐蚀性的论点。请把它安排在下一个循环中并行地开始?你知道吗


Tags: 代码importselfwebmessagedeftornadoclass
1条回答
网友
1楼 · 发布于 2024-10-02 16:32:23

存在两个问题:首先,您不能从一个协程中产生所有类型的对象,您必须产生一个Future或其他特殊的可屈服对象。所以当你的协同进程产生123123的收益时,Tornado抛出了一个“坏收益”异常。不幸的是,Tornado的websocket代码并不是为了捕获来自“on\u message”的异常而构建的,如果“on\u message”是一个协程,那么异常将以静默方式传递。见the warning at the bottom of the coroutine documentation。你知道吗

您的解决方案是从“mycoroutine”生成一个有效的对象。如果你只是想屈服一下,yield "gen.moment"

print "one"
yield gen.moment
print "two"

如果您想让“mycoroutine”并行运行,而不是阻塞“on\u message”,只需调用它而不产生:

mycoroutine(message)

但是!以这种方式调用协同程序意味着没有人在监听它是否抛出异常。确保捕获并记录“mycoroutine”中的所有异常,否则它们将以静默方式传递。你知道吗

相关问题 更多 >