• Ajax+Tornado模拟长、短轮询


    一、短轮询

      在传统的短轮询中,浏览器每隔一段时间向服务器发送请求,看服务器有无更新。缺点是效率低,因为服务器不是总有更新数据;再者,如果大量用户不停的请求服务器,会造成较大的负载压力。

      浏览器端,利用jQuery.ajax发送请求

     1 <html>
     2 <head>
     3     <title>Short Polling</title>
     4     <script type="text/javascript" src="lib/jquery.min.js"></script>
     5 </head>
     6 <body>
     7     <p>Short Polling - Unsorted list...</p>
     8     <ul></ul>
     9     <script>
    10         (function($) {            
    11             var polling = function() {
    12                 $.get('/polling', function(data){
    13                     $("ul").append("<li>"+data+"</li>");
    14                 });
    15             };
    16             interval = setInterval(polling, 3000);
    17         })(jQuery);
    18     </script>
    19 </body>
    20 </html>

      服务器端,tornado.httpserver响应请求(同步)

     1 import os
     2 import random
     3 import tornado.httpserver
     4 import tornado.ioloop
     5 import tornado.options
     6 import tornado.web
     7 
     8 from tornado.options import define, options
     9 
    10 define("port", default=8088, help="run on the given port", type=int)
    11 
    12 class MainHandler(tornado.web.RequestHandler):
    13     def get(self):
    14         self.write("Main page...")
    15 
    16 class ShortPollingHandler(tornado.web.RequestHandler):
    17     def get(self):
    18         num = random.randint(1,100)
    19         self.write(str(num))
    20 
    21 def main():
    22     tornado.options.parse_command_line()
    23     settings = {
    24         "static_path" : os.path.join(os.getcwd(), "public"),
    25     }
    26     application = tornado.web.Application([
    27         (r"/", MainHandler),
    28         (r"/polling", ShortPollingHandler),
    29     ], **settings)
    30     http_server = tornado.httpserver.HTTPServer(application)
    31     http_server.listen(options.port)
    32     print "server listening on port %d" % options.port
    33     tornado.ioloop.IOLoop.instance().start()
    34 
    35 if __name__ == "__main__":
    36     main()

      连接的平均时长0.5ms左右:由于浏览器端定时发送请求,如果连接在服务器端发生阻塞,则会造成服务器端负载压力上升;当服务器端无阻塞且无更新时,连接立即断掉,浏览器端的大量请求未能取得有效数据,效率低下。

    二、长轮询

      用户发出请求建立连接,当服务器端有数据返回后连接才会断掉,接着用户端发送一个新的连接请求。

      浏览器端,在jQuery.get的callback中重新发出连接请求

     1 <html>
     2 <head>
     3     <title>Long Polling</title>
     4     <script type="text/javascript" src="lib/jquery.min.js"></script>
     5 </head>
     6 <body>
     7     <p>Long Polling - Unsorted list...</p>
     8     <ul></ul>
     9     <script>
    10         (function($) {          
    11             var polling = function() {
    12                 $.get('/polling', function(data){
    13                     $("ul").append("<li>"+data+"</li>");
    14                     polling();
    15                 });
    16             };
    17             polling();
    18         })(jQuery);
    19     </script>
    20 </body>
    21 </html>

      服务器端,tornado.httpserver响应请求(异步)

     1 import os
     2 import time
     3 import random
     4 import tornado.httpserver
     5 import tornado.ioloop
     6 import tornado.options
     7 import tornado.web
     8 
     9 from tornado.options import define, options
    10 
    11 define("port", default=8088, help="run on the given port", type=int)
    12 
    13 
    14 class MainHandler(tornado.web.RequestHandler):
    15     def get(self):
    16         self.write("Main page...")
    17 
    18 class PollHandler(tornado.web.RequestHandler):
    19     @tornado.web.asynchronous
    20     def get(self):
    21         if self.request.connection.stream.closed():
    22             return
    23         num = random.randint(1, 100)
    24         tornado.ioloop.IOLoop.instance().add_timeout(
    25             time.time()+3,
    26             lambda: self.send(data=num, callback=self.get)
    27         )
    28              
    29     def send(self, data, callback):
    30         try:
    31             self.write(str(data))
    32             self.finish()
    33         except:
    34             pass
    35 
    36 def main():
    37     tornado.options.parse_command_line()
    38     settings = {
    39         "static_path" : os.path.join(os.getcwd(), "public"),
    40     }
    41     application = tornado.web.Application([
    42         (r"/", MainHandler),
    43         (r"/polling", PollHandler),
    44     ], **settings)
    45     http_server = tornado.httpserver.HTTPServer(application)
    46     http_server.listen(options.port)
    47     print "server listening on port %d" % options.port
    48     tornado.ioloop.IOLoop.instance().start()
    49 
    50 
    51 if __name__ == "__main__":
    52     main()

      连接的平均时长3s左右。

    三、参考

      1 - Browser 与Server 持续同步的作法介绍(Polling, Comet, Long Polling, WebSocket)

        http://www.josephj.com/entry.php?id=358

      2 - Browser和Server持续同步的几种方式(jQuery+tornado演示)

        http://qinxuye.me/article/ways-to-continual-sync-browser-and-server/

  • 相关阅读:
    数据结构笔记(第三章)
    数据结构笔记(第二章)
    Java第三阶段学习(四、缓冲流)
    Java第三阶段学习(三、字符流、转换流)
    Java第三阶段学习(二、IO流--------递归,字节流Stream)
    Java学习(异常类)
    Java学习(异常类练习题)
    Java学习(JDBC java连接数据库)
    Java学习(Map接口)
    Java学习(set接口、HashSet集合)
  • 原文地址:https://www.cnblogs.com/crazychris/p/2869966.html
Copyright © 2020-2023  润新知