我有很长的编程背景,但我是Python的新手,并且正在玩Tornado,为某个长轮询服务做原型。
我想要实现的是用户连接到例如example.com/get/1234,这是漫长的民意调查部分。 1234是用户ID。现在,它只是挂起并等待内容。然后用户使用新的选项卡/其他浏览器/其他计算机/等,并转到url,如example.com/set/1234?data=abcd,其中1234是用户ID,数据是内容为“abcd”的变量。现在发生这种情况时,第一个get请求应打印出数据“abcd”并完成请求。显然,用户ID允许多个用户同时使用该服务。所以简单地说:
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()
非常感谢所有人的帮助。提前谢谢!
答案 0 :(得分: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 + pubsub。我自己没有使用过,但有一个例子here。
答案 1 :(得分:1)
我确实设法解决了这个问题,找到了solution。
只是为了回顾一下其他人正在研究这个:我用user_id
将听众保存到一个字典中,当/set
被调用时,我向听众传达了相同的{{1} }}。如果有人感兴趣,我可以分享更多代码。