falsk websocket

官网地址:https://flask-socketio.readthedocs.io/en/latest/getting_started.html

安装

pip install flask-socketio==5.3.1

简单使用

项目目录结构如下:
image

server代码

import random
import time

from flask import Flask, render_template, request
from flask_socketio import SocketIO

app = Flask('__name__')
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)

connected_sids = set()  # 记录连接客户端


@app.route('/')
def index():
    return render_template('index.html')


@app.route('/test')
def test():
    return 'ok'


@socketio.on('connect')
def connect():
    connected_sids.add(request.sid)
    print(f'<{request.sid}>连接...')


@socketio.on('disconnect')
def disconnect():
    connected_sids.remove(request.sid)
    print(f'<{request.sid}>断开...')


@socketio.on('message')
def receiver(message):
    """收消息"""
    data = message['data']
    print(f'{request.sid} {data}')


def sender(data):
    """广播发送"""
    socketio.emit('my_response', {'data': random.randint(1, 100)})


@app.route('/send')
def send():
    while True:
        sender('111')
        time.sleep(10)


if __name__ == '__main__':
    socketio.run(app, host='0.0.0.0', debug=True)

client代码

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>WebSocket</title>
    <script src="https://cdn.staticfile.org/jquery/3.6.1/jquery.min.js"></script>
    <script src="https://cdn.staticfile.org/socket.io/4.5.2/socket.io.min.js"></script>
</head>
<body>
<h1>Flask-SocketIO Quickstart</h1>
<h2 id="sid">客户端</h2>
<h2>发消息</h2>
<input id="emit_data" value="Hello World!">
<button id="emit">发消息</button>
<h2>收消息</h2>
<div id="log"></div>
<script>
    var socket = io("ws://127.0.0.1:5000");

    socket.on("connect", function () {
        $("#sid").text("客户端:" + socket.id)
    });

    $("#emit").click(function () {
        socket.emit("message", {data: $("#emit_data").val()});
    });  // 点击按钮发消息

    socket.on("my_response", function (msg) {
        $("#log").append("<p>" + msg.data + "</p>");  // 收消息
    });
</script>
</body>
</html>

使用命名空间

目录结构

server代码

import random
import time

from flask import Flask, render_template, request
from flask_socketio import SocketIO, Namespace, emit

app = Flask('__name__')
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)

connected_sids = set()  # 记录连接客户端


@app.route('/')
def index():
    return render_template('index.html')


@app.route('/test')
def test():
    return 'ok'


class MyCustomNamespace(Namespace):
    def on_connect(self):
        connected_sids.add(request.sid)
        print(f'<{request.sid}>连接...')

    def on_disconnect(self):
        connected_sids.remove(request.sid)
        print(f'<{request.sid}>断开...')

    def on_my_event(self, data):
        emit('my_response', data)

    def on_receiver(self, msg):
        data = msg['data']
        print(f'{request.sid} {data}')


socketio.on_namespace(MyCustomNamespace('/test'))


def sender(data):
    """广播发送"""
    socketio.emit('my_response', {'data': random.randint(1, 100)})


@app.route('/send')
def send():
    while True:
        sender('111')
        time.sleep(10)


if __name__ == '__main__':
    socketio.run(app, host='0.0.0.0', debug=True)

client代码

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>WebSocket</title>
    <script src="https://cdn.staticfile.org/jquery/3.6.1/jquery.min.js"></script>
    <script src="https://cdn.staticfile.org/socket.io/4.5.2/socket.io.min.js"></script>
</head>
<body>
<h1>Flask-SocketIO Quickstart</h1>
<h2 id="sid">客户端</h2>
<h2>发消息</h2>
<input id="emit_data" value="Hello World!">
<button id="emit">发消息</button>
<h2>收消息</h2>
<div id="log"></div>
<script>
    var socket = io("ws://127.0.0.1:5000/test");

    socket.on("connect", function () {
        $("#sid").text("客户端:" + socket.id)
    });

    $("#emit").click(function () {
        socket.emit("receiver", {data: $("#emit_data").val()});
    });  // 点击按钮发消息

    socket.on("my_response", function (msg) {
        $("#log").append("<p>" + msg.data + "</p>");  // 收消息
    });
</script>
</body>
</html>

不同点

image

注意点

使用基于类的命名空间时,服务器接收的任何事件都将调度到名为带有on_前缀的事件名称的方法。例如,事件my_event将由名为的方法处理on_my_event。如果收到的事件没有在命名空间类中定义的相应方法,则忽略该事件。基于类的命名空间中使用的所有事件名称必须使用方法名称中合法的字符。

异常处理

@socketio.on_error()        # Handles the default namespace
def error_handler(e):
    pass

@socketio.on_error('/chat') # handles the '/chat' namespace
def error_handler_chat(e):
    pass

@socketio.on_error_default  # handles all namespaces without an explicit error handler
def default_error_handler(e):
    pass
posted @ 2022-10-26 09:35  一枚码农  阅读(20)  评论(0编辑  收藏  举报