响应在Tornado产生了结果

时间:2016-01-02 19:26:58

标签: python websocket celery tornado yield

我想通过websockets创建messenger。我的逻辑是:User_1通过tornado处理程序向User_2发送消息(json),在tornado服务器上检查消息(def send_message_to_RDB_parallel)(对RDB,PostgreSQL的一些请求)然后User_1收到回复,User_2收到消息。

检查对RDB(def send_message_to_RDB_parallel)的请求 - 可能会阻止我的龙卷风服务器。因为它我想通过Celery(使用RabbitMQ)或者只是产生它。据我所知,它可以帮助我解锁龙卷风服务器。但是我需要在完成任务后得到回复。我可以用Celery或不用它来启动它,但我无法得到响应..当我打破我的龙卷风服务器(按Ctrl-C)然后我看到一个错误,如“......对象不可调用”

如何获得回复并发送回复(self.write_message())?

在这个例子中,我尝试用yield

来做
class MessagesHandler(tornado.websocket.WebSocketHandler):
    ...

    def on_message(self, mess):
    ...
        self.send_message_to_RDB(thread_id=thread_id,
                                     sender_id=self.user_id,
                                     recipient_id=recipient_id,
                                     message=message['msg'],
                                     time=datetime.datetime.now(datetime.timezone.utc),
                                     check=True)
    ...                              

    @tornado.gen.coroutine
    def send_message_to_RDB(self, thread_id, sender_id, recipient_id, message, time, check):
        response = yield tornado.gen.Task(send_message_to_RDB_parallel(thread_id=thread_id,
                                             sender_id=sender_id,
                                             recipient_id=recipient_id,
                                             message=message,
                                             time=time,
                                             check=check))
        if response.result[0] is False:
            self.write_message(response.result[1])



def send_message_to_RDB_parallel(thread_id, sender_id, recipient_id, message, time, check=False):
    """
    Send message to rdb. Check thread. One recipient_id !
    """
  #  tf__ = False
    if check is True:
        if recipient_id == sender_id:
            return False, to_json_error(MessengerRecipientEqualSenderServerMessage[1])

        if User.objects.filter(id=recipient_id,
                               is_deleted=False,
                               is_active=True,
                               is_blocked=False).exists() is False:
            return False, to_json_error("Wrong User")
    ...    

    else:
        me = Message()
        me.text = message
        me.thread_id = thread_id
        me.sender_id = sender_id
        me.datetime = time
        me.save()

    return True, None

1 个答案:

答案 0 :(得分:1)

有一些常见错误:

  1. send_message_to_RDB_parallel即使没有回调参数也不是异步,但您尝试将其与gen.Task一起使用 - 不会设置任何结果
  2. on_message是一个协程,它在send_message_to_RDB中被调用,坚果它没有得到(等待)
  3. gen.Task接受一个函数(以及可选的附加参数)并运行它,但实际上你调用的代码却没有传递
  4. 由于2)不会引发任何进一步的错误,这样你就可以在^C之后看到它们。必须阅读http://www.tornadoweb.org/en/stable/guide/async.html

    <强>解决方案

    当然你可以使用芹菜并异步等待结果(Tornado celery integration hacks)..

    但如果您使用Postgres,我建议使用现有的异步库(Saving API output async using SQLAlchemy and Tornado):

    • momoko - postgres基于Tornado的客户端,它不是ORM,
    • aiopg - postgres基于asyncio的客户端(Tornado 4.3及以上版本),支持sqlalchemy查询构建器