2016-05-30 3 views
1

Я новичок в tornado.Я пытаюсь создать прокси-сервер чата с торнадо, я получил сообщение от веб-клиента, обычно ему просто нужно отправить его обратно, однако мне нужно отправить это сообщение на другой сервер во-первых, здесь возникает проблема, стоит много времени ждать ответа другого сервера, мне нужно сделать это без блокировки, но когда я использую анонимные методы торнадо, это вообще не работает, помогите мне ,Большое спасибо!Что делать, если у меня есть блокировка в on_message tornado.websocket?

Это часть моего псевдо-код:

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 

Итак, что я должен делать? спасибо

Но после того, как я Пересоздать мой код, он все блоки в part.I задач не знаю, почему, это еще часть моего кода 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) 

ответ

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) 
+0

Большое спасибо, господин, я так рад, что ваш ответ, я имею в виду, вы как раз так awesome.And я изменил мой код, но до сих пор не sovled что проблема, будет приятно снова ответить. Новый код в вопросе reedit, еще раз спасибо –

+0

Работник все равно должен быть в пуле потоков. –

+0

Большое спасибо –