一路狂飙

基于js/tornado的简单websocket通信

websocket简单介绍

因为web的基础http协议是无状态的,每个http请求都是一个socket短链接,因此只能由客户端向服务端发消息,而服务端不能主动向客户端发消息,服务器需要主动通知客户端的时候就无能为力了,因此诞生了websocket。

websocket只是一种协议,实现这种协议的服务端有很多种,今天我要聊是基于python,tornado框架的实现。->中文文档<-

websocket客户端

基于javascript的客户端

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服务端

 
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 = { "template_path": "."}
        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()

其他

  1. 心跳检测,由于websocket本质上是一个tcp的长连接,因此需要检测存活性
  2. 用户权限验证,需要在握手完成以后进行用户auth的操作
  3. 集群方式的用户数据同步,例如一个聊天室人太多,一个服务器扛不住,需要多台
  4. 容量限制,一个server链接的人太多了以后,为了保证已链接用户的服务质量,后面的用户需要排队
  5. 在https的网站里面需要用wss协议,这时候需要用nginx的反向代理做协议转换

以下为nginx的核心配置:

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";
    }
}