websocket简单介绍
因为web的基础http协议是无状态的,每个http请求都是一个socket短链接,因此只能由客户端向服务端发消息,而服务端不能主动向客户端发消息,服务器需要主动通知客户端的时候就无能为力了,因此诞生了websocket。
websocket只是一种协议,实现这种协议的服务端有很多种,今天我要聊是基于python,tornado框架的实现。->中文文档<-
websocket客户端
基于javascript的客户端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| var ws = new WebSocket("ws://xxx.ylkb.net:8080/ws");
ws.onopen = function(evt) { console.log("Connection open ..."); ws.send("Hello WebSockets!"); };
ws.onmessage = function(evt) { console.log( "Received Message: " + evt.data); ws.close(); };
ws.onclose = function(evt) { console.log("Connection closed."); };
|
websocket服务端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| import tornado.web import tornado.websocket import tornado.httpserver import tornado.ioloop class WebSocketHandler(tornado.websocket.WebSocketHandler): def check_origin(self, origin): return True def open(self): pass def on_message(self, message): self.write_message(u"Your message was: "+message) def on_close(self): pass class Application(tornado.web.Application): def __init__(self): handlers = [ (r'/ws', WebSocketHandler) ] settings = {} tornado.web.Application.__init__(self, handlers, **settings) if __name__ == '__main__': ws_app = Application() server = tornado.httpserver.HTTPServer(ws_app) server.listen(8080) tornado.ioloop.IOLoop.instance().start()
|
其他
- 心跳检测,由于websocket本质上是一个tcp的长连接,因此需要检测存活性
- 用户权限验证,需要在握手完成以后进行用户auth的操作
- 集群方式的用户数据同步,例如一个聊天室人太多,一个服务器扛不住,需要多台
- 容量限制,一个server链接的人太多了以后,为了保证已链接用户的服务质量,后面的用户需要排队
- 在https的网站里面需要用wss协议,这时候需要用nginx的反向代理做协议转换
以下为nginx的核心配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| map $http_upgrade $connection_upgrade { default upgrade; '' close; } upstream websocket { server 10.10.10.10:8010; } server { listen 8020; location / { proxy_pass http://websocket; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; } }
|