设为首页 收藏本站
查看: 780|回复: 0

[经验分享] python学习笔记

[复制链接]

尚未签到

发表于 2017-5-7 10:34:24 | 显示全部楼层 |阅读模式
继续笔记下关于tornado async一些学习知识:
Tornado支持long-polling,在其提供的demo中推荐参考的例子就是那个chat demo,我这里参考chat demo,提供一个简单的long-polling测试应用“用于统计当前在线人数,并保持最新数据至各个客户端的同步更新”。
1. 通过URL加一个参数name来模拟在线用户。
2. Ajax long polling 不只是server端的轮询,client端也需要保持一种请求轮询状态,因为当前的大多数web server都不支持基于单向的HTTP链接的双向通信,我们可以通过websockets,但是这个将HTTP转换成其他形式的协议的操作,目前大多数的浏览器并没有广泛支持,我们可以联想到HTML5 Websockets。我们可以用一种long-lived 链接方式(tornado支持的),用于server和client端之间的数据传输, 类似push-pull的方式,我觉得。
3. 这次的测试,暂没有提供基于重写on_connection_close来处理offline的用户(直接关闭浏览器),所以用户统计的数量只会随着访问数量的增加而增加 DSC0000.gif
Comet
我的测试代码,目前使用的是tornado 1.2.1
Server端:

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>


简单说明:
1.
通过简单的提供
global online = []
global count = 0
用于用户在线用户的统计
2.
http://localhost:8888/?name=a
http://localhost:8888/?name=b
通过不同的name来模拟各个用户
-----------------------------------------------
对于on_connection_close,the select()-base implements of IOLoop (non-Linux systems) 相关的实现是在tornado 1.2下有修补一些问题,详细可以参考
changelist :
https://github.com/facebook/tornado/commit/1221865747ecfde69a0463b9a0d77b3c5b87f320
但是根据Ben Darnell的建议,并没有在windows下测试过,目前还在学习、讨论中。
-----------------------------------------------
在使用tornado async时一些体验:
1. self.render(), self.redirect()其中已经包含了self.finish()操作,我们在写相关的async callback时候,需要注意这个,不应重复使用self.finish()
2. RequestHandler.async_callback 这个方法从1.1版本开始已经废除,类似代码(下面)应该不再使用,可以通过AsyncHTTPClient来实现异步请求

@tornado.web.asynchronous
def get(self):
...
self.check_for_last_numbers(callback=self.async_callback(self.on_finish))
...
def check_for_last_numbers(self, callback):
...


3. self.finish(),self.flush() 可以“简单的理解”为一种server端的push操作,但是实际实现中,建议使用self.finish(),tornado可以基于之前的cursor、session(secure cookie)来重用之前的connection。

笔记先分享到这里,欢迎大家讨论,共同学习

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-374101-1-1.html 上篇帖子: python学习笔记 下篇帖子: [Dive Into Python]内置函数类型--字典dictionary
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表