python使用websocket实现多端数据同步,多个websocket同步消息,断开链接自动清理
我使用的是flask_sock这个模块,我的使用场景是:可以让数据多端实时同步。在游戏控制后台和游戏选手的ipad上都可以实时调整角色的技能和点数什么的,所以需要这样的一个功能来实现数据实时同步。
下面是最小的demo案例:
from flask import Flask
from flask_sock import Sock
app = Flask(__name__)
sock = Sock(app)
# 创建全局的ws对象数组
ws_list = []
ws_closed = []
@app.route('/')
def index():
return "你好,世界"
@app.route('/ws')
def websocket():
return """
<!doctype html>
<html>
<head>
<title>Flask-Sock Demo</title>
</head>
<body>
<h1>Flask-Sock Demo</h1>
<div id="log"></div>
<br>
<form id="form">
<label for="text">Input: </label>
<input type="text" id="text" autofocus>
</form>
<script>
const log = (text, color) => {
document.getElementById('log').innerHTML += `<span style="color: ${color}">${text}</span><br>`;
};
const socket = new WebSocket('ws://' + location.host + '/echo');
socket.addEventListener('message', ev => {
log('<<< ' + ev.data, 'blue');
});
document.getElementById('form').onsubmit = ev => {
ev.preventDefault();
const textField = document.getElementById('text');
log('>>> ' + textField.value, 'red');
socket.send(textField.value);
textField.value = '';
};
</script>
</body>
</html>
"""
def handle_sync(data, self):
# 同步各端ws消息
for ws in ws_list:
if not ws.connected:
ws_closed.append(ws)
elif data and ws != self:
ws.send(data)
# 删除已断开的链接
for cl in ws_closed:
ws_list.remove(cl)
ws_closed.clear()
print(f"live num: {len(ws_list)}, done num: {len(ws_closed)}")
@sock.route('/echo')
def echo(self):
global ws_list
ws_list.append(self)
# 同步消息和关闭ws clear
handle_sync(None, self)
while True:
print(f"global ws list: {len(ws_list)}")
# 判断是断开连接还是还在链接
data = self.receive()
self.send(data)
# 同步消息和关闭ws clear
handle_sync(data, self)
if __name__ == '__main__':
app.run(host="0.0.0.0", port=8989)
当有ws链接进来的时候,有一个全局的数组存储所有的 ws_list 存储活着的websocket。ws_closed用来存储断开连接的ws信息,当每次建立新的链接或者一个ws收到消息,就检测每个链接的状态,并将信息同步到活着的所有ws链接。
程序启动之后,访问:http://192.168.110.196:8989/ws
就能建立一个ws链接,我创建了三个链接,当我在第一个上面发送消息的时候,后面两个就能将消息同步展示出来。任意一个页面发送数据,其他页面都会实时同步所有消息。
效果:
同步页面: