我正在尝试使用Tornado和JS Prototype库编写简单的Web应用程序。因此,客户端可以在服务器上执行长时间运行的作业。我希望,这项工作以异步方式运行 - 以便其他客户可以查看页面并在那里做一些事情。
我在这里得到了什么:
#!/usr/bin/env/ pytthon
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
from tornado.options import define, options
import os
import string
from time import sleep
from datetime import datetime
define("port", default=8888, help="run on the given port", type=int)
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.render("templates/index.html", title="::Log watcher::", c_time=datetime.now())
class LongHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
def get(self):
self.wait_for_smth(callback=self.async_callback(self.on_finish))
print("Exiting from async.")
return
def wait_for_smth(self, callback):
t=0
while (t < 10):
print "Sleeping 2 second, t={0}".format(t)
sleep(2)
t += 1
callback()
def on_finish(self):
print ("inside finish")
self.write("Long running job complete")
self.finish()
def main():
tornado.options.parse_command_line()
settings = {
"static_path": os.path.join(os.path.dirname(__file__), "static"),
}
application = tornado.web.Application([
(r"/", MainHandler),
(r"/longPolling", LongHandler)
], **settings
)
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
if __name__ == "__main__":
main()
这是服务器部分。它有主视图(显示小问候,当前服务器时间和ajax查询的url,执行长时间运行的作业。如果你按一个按钮,一个长时间运行的作业执行。并且服务器挂起:(我无法查看没有页面,而这项工作正在进行中。 这是模板页面:
<html>
<head>
<title>{{ title }}</title>
<script type="text/javascript" language="JavaScript" src="{{ static_url("js/prototype.js")}}"></script>
<script type='text/javascript' language='JavaScript'>
offset=0
last_read=0
function test(){
new Ajax.Request("http://172.22.22.22:8888/longPolling",
{
method:"get",
asynchronous:true,
onSuccess: function (transport){
alert(transport.responseText);
}
})
}
</script>
</head>
<body>
Current time is {{c_time}}
<br>
<input type="button" value="Test" onclick="test();"/>
</body>
</html>
我做错了什么?如何使用Tornado和Prototype(或jQuery)实现长池化
PS:我看过Chat示例,但它太复杂了。无法理解它是如何工作的:(
PSS全部下载example
答案 0 :(得分:15)
Tornado是单线程Web服务器。 wait_for_smith
方法中的while循环阻止了Tornado。
您可以像这样重写该方法:
def wait_for_smth(self, callback, t=10):
if t:
print "Sleeping 2 second, t=%s" % t
tornado.ioloop.IOLoop.instance().add_timeout(time.time() + 2, lambda: self.wait_for_smth(callback, t-1))
else:
callback()
您需要在顶部添加import time
才能使其正常工作。
答案 1 :(得分:1)
function test(){
new Ajax.Request("http://172.22.22.22:8888/longPolling",
{
method:"get",
asynchronous:true,
onSuccess: function (transport){
alert(transport.responseText);
}
})
}
应
function test(){
new Ajax.Request("/longPolling",
{
method:"get",
asynchronous:true,
onSuccess: function (transport){
alert(transport.responseText);
}
})
}
答案 2 :(得分:0)
我已将Tornado的聊天示例转换为gevent。请查看the live demo here和the explanation and source code here。
它使用轻量级用户级线程(greenlets),在速度/内存使用方面与Tornado相当。但是,代码很简单,您可以在处理程序中调用sleep()和urlopen()而不会阻塞整个过程,并且可以生成执行相同操作的长时间运行的作业。在引擎盖下,应用程序是异步的,由用C(libevent)编写的事件循环提供支持。
您可以阅读introduction here。
答案 3 :(得分:0)
我读过Ted Roden所说的"Building the Realtime User Experience"这本书,非常有帮助。我已经设法使用Tornado(python)创建一个复杂的实时聊天系统。我建议阅读本书以及John Goerzen撰写的"Foundations of Python Network Programming"。