当我在on_message tornado.websocket中有阻塞内容时,我该怎么办?

时间:2016-05-30 10:55:32

标签: python websocket tornado

我是龙卷风的新手。我正在尝试使用龙卷风建立聊天服务器代理,我从网络客户端收到消息,通常只需要将其发送回来,但是,我需要发送这些消息首先到另一台服务器,问题是,等待其他服务器响应需要花费大量时间,我需要让它无阻塞,但是当我使用龙卷风的匿名方法时,它不起作用好的,帮助我,非常感谢你!

这是我伪代码的一部分:

class ClientWSConnectienter(websocket.WebSocketHandler):

_thread_pool = ThreadPoolExecutor(20)

def initialize(self, room_handler):
    #chat room initiate
    self.__rh = room_handler

@run_on_executor(executor='_thread_pool')
def worker(self,msg):
    #send the msg to another server
    pmessage=send_msg_to_server(msg) 
    return pmessage

@tornado.web.asynchronous
@tornado.gen.coroutine
def on_message(self, message):
    #this will blocking for too much time,and I want make it no-blocking
    pmessage=yeild worker(msg) 
    #send the recive pmessage to others client
    room.write_message(pmessage) 
    self.finish()
显然,它没有用,我有这样的事情:

error:websocket cannot use this method

那么,我该怎么办?非常感谢

但是在我编写代码之后,它仍然会阻塞任务部分。我不知道为什么,这仍然是我的代码的一部分 Re_edit:

class ClientWSConnection(websocket.WebSocketHandler):

def initialize(self, room_handler):
    self.queue = tornado.queues.Queue()

def open(self, client_id):
    IOLoop.current().spawn_callback(self.loop)

def on_message(self, message):
    self.queue.put(msg)

def on_close(self):
    self.queue.put(None)

@coroutine
def loop(self):
    while 1:
        msg=yield self.queue.get()
        if msg is None:
            return
        msg=yield self.worker(msg)
        pmessage = msg
        room.write_message(pmessage)
@coroutine
def worker(self,msg):
    #need to send the other server,blocking here
    time.sleep(10)
    raise Return(msg)

1 个答案:

答案 0 :(得分:2)

我认为错误消息来自您对finish()的调用,这对于websockets没有意义(您的意思是close()吗?)。 (此外,无需同时使用@asynchronous@coroutine;仅@coroutine就足够了)

但是有一个更大的问题:请记住,当重写超类中定义的方法时,如果文档说明你可以只使它们成为协程(因为协程的调用与常规方法不同)。 WebSocketHandler.on_message目前(从Tornado 4.3开始)不支持协同程序。

因此,您需要使用队列将其移交给另一个任务。像这样:

class MyHandler(WebSocketHandler):
    def initialize(self):
        self.queue = tornado.queues.Queue()

    def on_open(self):
        IOLoop.current().spawn_callback(self.loop)

    def one_message(self, msg):
        self.queue.put(msg)

    def on_connection_close(self):
        self.queue.put(None)

    @coroutine
    def loop(self):
        while True:
            msg = yield self.queue.get()
            if msg is None:
                return
            pmessage = yield self.worker(msg)
            self.write_message(pmessage)