Http协议是一种请求响应式协议, 不允许服务端主动向客户端发送信息.

短轮询是一种简单的实现服务端推送消息的解决方案, 客户端以一定间隔自动向服务端发送刷新请求, 服务端返回要推送的消息作为响应.

短轮询存在严重缺陷:

  • 短轮询需要进行高频率的网络通信, 且收到大多数轮询请求时服务端没有消息需要推送.

  • 需要维护大量Http连接, 严重消耗资源

如果手写一个短轮询的话你会发现, 短轮询带来的问题不止这些.

长轮询

长轮询是客户端向服务端发送一个刷新请求, 并保持连接打开. 服务端收到请求后不立即响应,等到需要推送消息时再返回. 然后, 客户端再次发送刷新请求并等待推送.

长轮询不再需要频繁发送刷新请求, 但是长期等待的Http连接可能断开, 需要考虑异常处理.

长轮询请求等待过程中服务端处理进程不能被阻塞, tornado的异步IO机制可以方便的使用长轮询.

import tornado.httpserver
from tornado.ioloop import IOLoop
import tornado.options
import json
from tornado.web import Application, RequestHandler, asynchronous class ChatApp(Application):
def __init__(self):
handlers = [
(r'/new-message', NewMsgHandler),
(r'/update-message', UpdateMsgHandler)
]
super(ChatApp, self).__init__(self, handlers=handlers)
self.cache = [] class NewMsgHandler(RequestHandler):
def __init__(self, app):
self.app = app def post(self):
msg = self.get_argument('msg')
self.app.cache.append(msg) class UpdateMsgHandler(RequestHandler):
def __init__(self, app):
self.app = app @asynchronous
def post(self):
if self.request.connection.stream.closed():
return
response_json = json.dumps(self.app.cache)
self.write(response_json)
self.finish() def main():
tornado.options.parse_command_line()
app = ChatApp()
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start() if __name__ == '__main__':
main()

示例的完整代码,请去草民的仓库

这篇博客提供了一个更为强大的基于长轮询的聊天室, 而且草民非常喜欢他的代码风格.

tornado的长轮询聊天室例子分析

长连接断开的处理机制可以参考这篇文章

WebSocket

WebSocket是HTML5协议中提出的客户-服务器通信协议, 它允许双方以类似TcpSocket的方式进行通信.

它基于标准Http协议实现, 但使用新的ws://URL格式.

Tornado在websocket模块中提供了一个WebSocketHandler类,

  • open方法在一个新的WebSocket连接打开时被调用,

  • on_message方法在连接接收到新的消息时被调用

  • on_close方法在客户端关闭时被调用

  • write_message(message, binary=False)方法可以通过WebSocket向对方发送数据

      - 若binary=False, message可以是string或者dict(会被自动编码为JSON), 
    
      - 若binary=True, message可以是任意byte string

继承WebSocketHandler并重写自己上述方法,实现基于WebSocket的应用.

来自tornado官方文档的示例:

class EchoHandler(WebSocketHandler):

	def allow_draft76(self):
return True def check_origin(self, origin):
return True def open(self):
print "new client opened" def on_close(self):
print "client closed" def on_message(self, message):
self.write_message(message)

allow_draft76check_origin用于进行安全性校验, 只有它们都返回True时WebSocket才能正常连接.

tornado WebSocketHandler文档

Python WebSocket

WebSocket虽然是为Web应用设计的, 为了减轻后端的开发压力可以采用WenSocket代替Tcp Socket与后端交互.

Websocket-client是Python Websocket支持包,可以使用pip安装:

pip install websocket-client

PyPi websocket-client

websocket-client提供了几个低级API:

  • 建立websocket连接

ws = create_connection("ws://echo.websocket.org/")

  • 发送消息

ws.send(msg)

  • 接收消息

result = ws.recv()

  • 关闭连接

ws.close()

websocket也提供了JS风格的API, 来自官方文档的示例:

import websocket
import thread
import time def on_message(ws, message):
print message def on_error(ws, error):
print error def on_close(ws):
print "### closed ###" def on_open(ws):
def run(*args):
for i in range(3):
time.sleep(1)
ws.send("Hello %d" % i)
time.sleep(1)
ws.close()
print "thread terminating..."
thread.start_new_thread(run, ()) if __name__ == "__main__":
websocket.enableTrace(True)
ws = websocket.WebSocketApp(
"ws://echo.websocket.org/",
on_message = on_message,
on_error = on_error,
on_close = on_close
)
ws.on_open = on_open
ws.run_forever()

更多信息请参见Github websocket-client

最新文章

  1. Servlet中转发和重定向的区别
  2. 高性能网站架构设计之缓存篇(4)- Redis 主从复制
  3. django静态文件数据库设置
  4. PeCheck
  5. Apache Kafka 分布式消息队列中间件安装与配置 转载
  6. Redis 起步
  7. C# aspnetpager分页
  8. 使用DateDiff方法获取日期时间的间隔数
  9. 第二十八条:利用有限制通配符来提升API的灵活性
  10. 西湖论剑2019复现-Web之首家线上赌场上线啦
  11. sklearn使用——梯度下降及逻辑回归
  12. flex布局justify-content属性和align-items属性设置
  13. 使用spark集成kudu做DDL
  14. git修改本地和远程仓库名称的解决方法
  15. FileAttributes Enum
  16. Java乱码解决之道
  17. git之回退
  18. centos 虚拟机中修改屏幕分辨率
  19. 【ORACLE】oracle 日志文件管理
  20. 单调队列:temperature

热门文章

  1. 一起学习MVC(4)Controllers的学习
  2. Alwayson--辅助副本状态
  3. ExceptionLess ASP.NET MVC 异常日志框架
  4. Windows下安装NTP服务器
  5. .Net 百度经纬度转高德
  6. Backbone学习笔记 - View篇
  7. Eclipse (JavaEE版)中修改web项目的访问路径
  8. HDU 6198(2017 ACM/ICPC Asia Regional Shenyang Online)
  9. badboy录制网站出现css样式混乱,网页的图标点击没反应
  10. webpack初学者(1)