import os
import string
import time
import logging
from datetime import datetime
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.httpclient
from tornado.options import define, options
define("port", default=8888, help="run on the given port", type=int)
online = []
count = 0
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.user = self.get_argument("name", None)
self.render("templates/stack_p312a.html", title="Online number testing", c_time=datetime.now(), user=self.user)
class LongPollingHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
def get(self):
global online, count
self.user = self.get_argument("name", None)
if self.user not in online:
logging.info("user : " + self.user)
online.append(self.user)
http = tornado.httpclient.AsyncHTTPClient()
appURL = self.request.protocol + "://" + self.request.host
http.fetch(appURL + "/internal-polling", self._on_finish)
'''push to the client'''
def _on_finish(self, response):
if self.request.connection.stream.closed():
return
self.write("welcome %s, current online number(s) %s" % (self.user, response.body))
self.finish()
'''
def on_connection_close(self):
TODO, testing
'''
class InternalPollingHandler(tornado.web.RequestHandler):
'''
The internal polling for the new online member which will be counted into
the global online list, and then asynchronously push the latest data to the connected client,keep in a long-polling status.
'''
def get(self):
global online, count
logging.info("count : " + str(count))
logging.info("online : " + str(len(online)))
if count != len(online):
count += 1
self.get()
else:
self.write(str(count))
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"/long-polling", LongPollingHandler),
(r"/internal-polling", InternalPollingHandler),
], **settings
)
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
if __name__ == "__main__":
main()
Client端(stack_p312a.html):
<html>
<head>
<title>{{ title }}</title>
<script type="text/javascript" language="JavaScript" src="{{ static_url("jquery-1.5.1.min.js")}}"></script>
<script type='text/javascript' language='JavaScript'>
function test(){
window.setTimeout(function(){
$.ajax({
url : '/long-polling?name={{ user }}',
success : function(data){
$("#num").text(data);
}
});
test();
}, 5000);
}
</script>
</head>
<body>
Current time is {{c_time}}
<br>
<input type="button" value="Test" />
<div id="num"></div>
</body>
</html>