websocket
2021-04-13 10:27
YPE html>
标签:ike its rtb 管道 浏览器 input框 city key contain
阅读目录
一、websockt
二、实战应用
1 websocket
1.1 简述
WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
1.2 原理
1.2.1 一个小例子熟悉websocket原理
a.启动服务端,等待客户端连接
b.小强来连接,服务端允许
c.小强立即发送一个“握手信息”
GET /xxxx HTTP/1.1\r\n
Host: 127.0.0.1:8002\r\n
Connection: Upgrade\r\n
Pragma: no-cache\r\n
Cache-Control: no-cache\r\n
Upgrade: websocket\r\n
Origin: http://localhost:63342\r\nSec-WebSocket-Version: 13\r\n
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: zh-CN,zh;q=0.9\r\n
Cookie: csrftoken=ojyruuaF3Tk0OToIrXy1sRSdSk3SeDgd6Ti3jocEXAuEExaMtxjhJglpenj6Iq8F\r\n
Sec-WebSocket-Key: 4NZY2fTOr691upgWe2yq7w==\r\n ######## 这里 ########
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\n\r\n
d.服务端接收握手信息后需要对数据进行加密,给客户端返回
- 4NZY2fTOr691upgWe2yq7w + magic_string(魔法字符串)
- sha1
- base64
response_tpl = "HTTP/1.1 101 Switching Protocols\r\n" "Upgrade:websocket\r\n" "Connection: Upgrade\r\n" "Sec-WebSocket-Accept: 加密之后的结果\r\n" "WebSocket-Location: ws://127.0.0.1:8002\r\n\r\n"
通信建立,双方可以进行互相通信:
e.小强给服务端发送消息:
读取第二个字节的后7位
127:10,4,数据
126:4,4,数据
f.服务端给客户端发送消息:
token = b"\x81"
length = len(msg_bytes)
if length
1.3 socket.io与websocket
- https://www.jianshu.com/p/2ec3d20341ab
1.4 python实现示例
- flask-socketio文档: https://flask-socketio.readthedocs.io/en/latest/
1.5 golang实现示例
1.5.1 后端
package main
import (
"errors"
"fmt"
"net/http"
"github.com/gorilla/websocket"
"sync"
"time"
)
var wsUpgrader = websocket.Upgrader{
//允许所有的cors跨域请求
CheckOrigin: func(r *http.Request) bool {
return true
},
}
type wsMessage struct {
messageType int
data []byte
}
type wsConnection struct {
wsSocket *websocket.Conn //底层websocket
inChan chan *wsMessage //读队列
outChan chan *wsMessage //写队列
mutex sync.Mutex //避免重复关闭管道
isClosed bool
closeChan chan byte //关闭通知
}
func(wsConn *wsConnection) wsReadLoop(){
for{
//读取一个message
mesType,data,err := wsConn.wsSocket.ReadMessage()
if err != nil{
goto error
}
req := &wsMessage{messageType:mesType, data:data}
//放入请求队列
select{
case wsConn.inChan
1.5.2 前端
Click "Open" to create a connection to the server,
"Send" to send a message to the server and "Close" to close the connection.
You can change the message and send multiple times.
2 实战应用
2.1 协作编辑
2.1.1 简介
多人实时操作一个资源,如钉钉协作excel文档,更多可以了解下面两部分内容
- https://www.cnblogs.com/powertoolsteam/p/onlineexcel.html
- https://www.jianshu.com/p/a3b350063cb5
2.1.2 需求实现
- web端多人在线协作编辑表格,python+flask+vue+socket.io实现
2.1.3 前端
协作编辑
名称
年龄
性别
爱好
技能
2.1.4 后端
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
CORS(app, supports_credentials=True, resources=r'/*') # http跨域问题
socketio = SocketIO(app, async_mode=async_mode, cors_allowed_origins='*') # cors_allowed_origins解决跨域
@app.route('/input-change', methods=['POST']) # http协议接受input change信息
def input_change():
"""
broadcast=True,发送广播,所有连接到socket.io的链接都会接受到信息
"""
emit('input-change', request.json, broadcast=True, namespace='/test')
return "success!"
@socketio.on('connect', namespace='/test')
def mtest_connect():
global thread
with thread_lock:
if thread is None:
thread = socketio.start_background_task(background_thread)
print("靓仔你来了呀...")
emit('my_response', {'data': 'Connected', 'count': 0})
@socketio.on('disconnect', namespace='/test')
def mtest_disconnect():
print('Client disconnected', request.sid)
if __name__ == '__main__':
socketio.run(app, debug=True)
2.1.5 总结
- 简单了实现了需求,但是协作编辑远远比这个要复杂的多,代码后端的处理直接选用了广播模式,真实场景肯定会有所偏差。这里推荐一个优秀的前端excel编辑器-葡萄城spreadjs
2.2 实时聊天室
github - 协作编辑及实时聊天室
websocket
标签:ike its rtb 管道 浏览器 input框 city key contain
原文地址:https://www.cnblogs.com/zhangliang91/p/12266135.html