用Tornado 构建一个 Comet 应用
Comet -- 基于 HTTP 长连接、无须在浏览器端安装插件的“服务器推”技术为“Comet”,这里介绍用Tornado 构建一个 Comet 应用的经验。
关于 Comet
Comet 指的是一种 Web 应用程序的架构。在这种架构中,客户端程序(通常是浏览器)不需要显式的向服务器端发出请求,服务器端会在其数据发生变化的时候主动的将数据异步的发送给客户端,从而使得客户端能够及时的更新用户界面以反映服务器端数据的变化。
这种架构既不同于传统的 Web 应用,也不同于新兴的 Ajax 应用。在传统的 Web 应用中,通常是客户端主动的发出请求,服务器端生成整个 HTML 页面交给客户端去处理。在 Ajax 应用中,同样是客户端主动的发出请求,只是服务器通常返回的是 XML 或是 JSON 格式的数据,然后客户端使用这些数据来对页面进行局部更新。Comet 架构非常适合事件驱动的 Web 应用和对交互性和实时性要求很强的应用。这样的应用的例子包括股票交易行情分析、聊天室和 Web 版在线游戏等。
用 Tornado 构建
说明1:使用此decorator即可以把get方法non-blocking化
说明2:non-blocking化的请求必须调用self.finish()完成请求
说明3:如果需要sleep等待,应该使用Tornado的IOLoop的add_timeout方法。使用其他休眠方法如time.sleep会block住当前线程,而Tornado是一个单线程Server,会导致其他请求无法执行的问题。
此时执行comet.py,一个non-blocking的server端已经搭建成功。
要注意的问题是,如果不加超时机制,服务端会不断执行,即使客户端已经断开。因此还需自己实现超时机制。
构建代码
#!/usr/bin/env python
import tornado.httpserver
import tornado.ioloop
import tornado.web
class MainHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous #说明1
def get(self):
some_async_func(callback=self.wait)
def wait(self, result):
if result:
self.write(result)
self.finish() #说明2
else:
tornado.ioloop.IOLoop.instance().add_timeout(time.time() + 0.5,lambda: some_async_func(callback=self.wait))
#说明3
application = tornado.web.Application([
(r"/", MainHandler),
])
if __name__ == "__main__":
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(8999)
tornado.ioloop.IOLoop.instance().start()
超时设置
在Nginx 配置里添加超时机制
upstream frontends {
server 127.0.0.1:8999;
}
server {
listen 8888;
location / {
proxy_read_timeout 1800;
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_pass http://frontends;
}
}
注意问题
需要特别指出的是,要根据上述应用的超时机制,设置proxy_read_timeout,proxy_read_timeout 必须大于应用的超时。否则将会有504请求返回。 它说明由 nginx 向tornado请求了长连接以后,等到1800秒之后,如果tornado还没有返回。则nginx返回504 Gateway Timeout给客户端浏览器。
发表第一条评论!
相关推荐
小工具
标签
最近发表
- Mac 关闭 Microsoft 自动更新
- Mac 登录 App Store 出现“发生了未知错误”的解决方法
- 老笔记本改造为无风扇静音主机方案
- 自己组装21瓦低功耗家庭爬虫、文件、web服务器
- 微信视频号尝鲜体验
- Ubuntu/Debian 查看CPU温度的方法
- 在Ubuntu/debian Server 系统使用Chrome 无头浏览模式
- 换手机后 Google 身份验证器 Google Authenticator 数据迁移的简单方法
- 使用Golang selenium WebDriver 自动登录微博
- 在 Ubuntu 或其它 GNU/Linux 系统下安装 Debian
- Mac 下制作 USB ubuntu/debian 系统启动、安装盘的几种方法
- ubuntu/debian 下自行编译 OpenWRT 固件
- 宅家自己动手换手机屏幕掉坑记
- 路由 UBNT ER-X 官方固件升级及开启硬件加速的方法
- 在 Nginx 和 Golang web 上抢先体验 QUIC
- 从UserAgent识别搜索引擎并判断真假蜘蛛
最近浏览
- go get 使用socks5 代理安装依赖库
- Openwrt 路由上开启BBR
- Golang 实现 GBK、Big5、UTF-8 之间的转换
- 换手机后 Google 身份验证器 Google Authenticator 数据迁移的简单方法
- Linux 系统永久设置ulimit
- Mac 登录 App Store 出现“发生了未知错误”的解决方法
- 在国外vps 上配置nginx 作反向代理访问国外网站
- OpenWrt 国内源
- Nginx 服务器上传大文件经常中断的解决方法
- Openwrt 使用USB 4G 上网卡共享网络
- python form-data post上传数据简便方法
- 路由 UBNT ER-X 官方固件升级及开启硬件加速的方法
- go2o: 一个完整的golang 商业开源项目
- Spotify开源的Python图表生成库chartify
- linux vim 中文显示乱码的解决方法
- Golang 正则切割字符串