什么是WebSocket?
WebSocket是使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动给客户端发送数据,在WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建永久性的链接,并进行双向数据传输.
WebSocket的属性
0 表示链接尚未建立
1 表示已经建立链接,可以进行通信
2 表示连接正在关闭
3 表示连接已经关闭或者连接不能打开
WebSocket事件
WebSocket方法
Web框架
轮询:
- http
- 每秒钟发起至少100次,请求收取信息
- 客户端有一定的处理能力
- 服务器有一定的处理速度
缺点:客户端服务器,资源浪费严重,带宽浪费
长轮询:
- http
- 先去连接服务器,不断开连接,保持一定的时间,断开瞬间再次发起连接
- 浪费服务器资源严重
- 节省客户端资源
- 相对实时性消息
长连接
- 基于http发起握手
- 保持和服务器的的长连接用不断开,除非有一端主动发起请求
- 在客户端和服务器上各有一个轮询
- 双端分担压力
- 消息及时性
缺点:占用连接资源,占用网络资源
基于WebSocket实现的用例
1 from flask import Flask, render_template, request
2 from geventwebsocket.handler import WebSocketHandler
3 from gevent.pywsgi import WSGIServer
4 from geventwebsocket.websocket import WebSocket
5
6 app = Flask(__name__)
7 # wsgi.websocket = <geventwebsocket.websocket.WebSocket object at 0x0000000003BC8528>,
8 user_scoket_list = []
9
10
11 @app.route("/conn_ws")
12 def ws_server():
13 user_socket = request.environ.get("wsgi.websocket") # type:WebSocket
14 user_scoket_list.append(user_socket)
15
16 while 1:
17 msg = user_socket.receive()
18 for i in user_scoket_list:
19 i.send(msg)
20
21
22 @app.route("/")
23 def index():
24 return render_template("web.html")
25
26 if __name__ == '__main__':
27
28 http_server= WSGIServer(("0.0.0.0",8888),app,handler_class=WebSocketHandler)
29 http_server.serve_forever()
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>群聊</title>
6 </head>
7 <body>
8 <input type="text" id="send_str">
9 <button id="send_btn" onclick="send()">发送消息</button>
10 <p>
11
12 <div id="char_list">
13
14 </div>
15 </p>
16 </body>
17 <script type="application/javascript">
18
19 var ws = new WebSocket("ws://192.168.11.50:8888/conn_ws");
20 ws.onmessage = function (messageEvent) {
21
22 console.log(messageEvent.data);
23 var ptag = document.createElement("p");
24 ptag.innerText = messageEvent.data;
25 document.getElementById("char_list").appendChild(ptag);
26
27
28 };
29 function send() {
30 var send_str = document.getElementById("send_str").value;
31 ws.send(send_str)
32 }
33
34 </script>
35 </html>
WebSocket的工作原理
1.握手
客户端: Sec-WebSocket-Key
响应端: base64(shal(Sec-WebSocket-Key + magic_string))
2.解密
与127进行"与"为运算,结果是两个数的最小值
1. == 127 第3-10个字节表示该数据的长度
2. == 126 第3-4个字节表示该数据的长度
3. <= 125 当前这个数字就是WebSocket发送的数据长度
WebSocket典型的握手
客户端请求
1 GET / HTTP/1.1
2 Upgrade: websocket
3 Connection: Upgrade
4 Host: example.com
5 Origin: http://example.com
6 Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ==
7 Sec-WebSocket-Version: 13
服务端回应
1 HTTP/1.1 101 Switching Protocols
2 Upgrade: websocket
3 Connection: Upgrade
4 Sec-WebSocket-Accept: fFBooB7FAkLlXgRSz0BT3v4hq5s=
5 Sec-WebSocket-Location: ws://example.com/