falsk websocket
官网地址:https://flask-socketio.readthedocs.io/en/latest/getting_started.html
安装
pip install flask-socketio==5.3.1
简单使用
项目目录结构如下:
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)}, namespace='/test')
@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>
不同点
注意点
使用基于类的命名空间时,服务器接收的任何事件都将调度到名为带有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