Python uses websocket to achieve multi-end data synchronization, multiple websockets synchronize messages, and automatically clean up when disconnected links

I use the flask_sock module. My usage scenario is: it can synchronize data from multiple ends in real time. The character's skills and points can be adjusted in real time on both the game control background and the player's iPad, so such a function is needed to achieve real-time data synchronization.

The following is the smallest demo case:

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)

When a ws link comes in, there is a global array to store all ws_list to store live websockets. ws_closed is used to store disconnected ws information. Every time a new link is established or a ws receives a message, the status of each link is detected and the information is synchronized to all living ws links.

After the program starts, visit: http://192.168.110.196:8989/ws

I can create a ws link. I created three links. When I send a message on the first one, the latter two can display the message synchronously. When any page sends data, other pages will synchronize all messages in real time.

Effect:

 Sync page:

Guess you like

Origin blog.csdn.net/weixin_44786530/article/details/133072202