2012-02-17 72 views
1

我有很长的编程背景,但是对Python来说是新手,并且正在与Tornado一起玩,为某个长轮询服务创建原型。如何在数据可用时完成Tornado长轮询请求

我想要实现的是用户连接到说example.com/get/1234,这是长期民意调查的一部分。 1234是用户标识。目前,它只是挂起并等待内容。然后,用户使用新标签页/其他浏览器/其他计算机/等,并转到url,如example.com/set/1234?data=abcd,其中1234是用户标识,数据是内容为“abcd”的变量。现在,当发生这种情况时,第一个获取请求应该打印出数据“abcd”并完成请求。用户标识显然用于允许多个用户同时使用该服务。所以,简单地说:

1)进入example.com/get/1234 - >等待 2)在另一个选项卡,打开example.com/set/1234?data=abcd 3)此请求后,右,第一请求打印出abcd并完成

下面是我一直在尝试的东西,但我并没有真正推进,也找不到适当的Google关键字来解决这个问题。

class GetHandler(tornado.web.RequestHandler): 
    @tornado.web.asynchronous 

    # Getting user ID is working 
    def get(self, user_id): 

     # This is something I'm not sure is right, but found it in an 
     # example. I haven't created the code_received function yet, 
     # nor know if it should be here? Should the code_received 
     # and connection finishing be called from the /set part? 

     cursor = self.get_argument("cursor", None) 
     self.wait_for_code(self.code_received, cursor=cursor) 

    def code_received(self, data) 
     self.write(data) 
     self.finish() 

所有帮助非常感谢。提前致谢!

回答

1

我实际上设法解决了这个问题,发现了solution

只是为了以防别人概括为寻找到这一点:我救了听众的字典与user_id/set叫,我传递消息监听器具有相同user_id。如果有人有兴趣,我可以分享更多的代码。

1

简单的解决方法是添加一个超时回调

class GetHandler(tornado.web.RequestHandler): 

    @tornado.web.asynchronous 
    def get(self, user_id):  

     def check(): 
      # here you must implement something to discover if the result exists 
      # for example, you can keep a dictionary with id : result 
      # so initially 1234 : None 
      # after setting 1234 : someVal (this happens from the SetHandler) 
      # then if below succeeds 
      if there_is_a_result: 
       self.write(result) 
       self.finish() 
      else: # result not ready, add another timeout callback 
       tornado.ioloop.IOLoop.instance().add_timeout(datetime.timedelta(0.00001), check) 

     tornado.ioloop.IOLoop.instance().add_timeout(datetime.timedelta(0.00001), check) 

编辑:一个更好的解决办法是使用WebSockets + Redis的+发布订阅。我自己没有用过这个,但是有一个例子here

+0

谢谢你回答@hymloth!但是这个解决方案基本上会循环并不断执行比较代码 - 当用户数量增长时,这不会导致性能问题吗?如果是这样,有没有办法在等待数据输入的同时“挂起”请求? – MonkeyPetteri 2012-02-17 17:26:57

+0

感谢您的更新@hymloth - 我正在考虑它,但似乎Firefox 3.x不支持websockets ..这是一个要求。任何其他想法? – MonkeyPetteri 2012-02-18 17:44:52

相关问题