# Flask使用flask_socketio实现websocket
下面是案例,是我自己用来测试使用的,可以直接运行的。详细的使用请看官网 (opens new window)
websocket主要应用于客户端和服务端双向通信的。
# 前端实现
使用socket.io.min.js
是node.js的一个websocket库,首先创建socket. emit
是向后端发送消息, message
是该条消息的名称,后面是发送消息的数据。on
是注册接受消息的事件,获取后端传过来的数据. namespace
是指一类的消息。当连接成功时,会触发connect
事件,连接关闭时,触发disconnect
事件。
<html>
<head>
<script type="text/javascript"
src="https://code.jquery.com/jquery-3.4.0.min.js"></script>
<script type="text/javascript"
src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>
<script type="text/javascript" charset="utf-8">
$(document).ready(function () {
namespace = "/wechat"
var socket = io.connect('http://' document.domain ':' location.port namespace);
socket.emit("message", { "data": "zhangsan" })
socket.on('connect', function (data) {
socket.emit('message', { 'data': 'I'm connected!' });
});
socket.on('disconnect', function(data){
socket.emit('message', { 'data': 'I'm disconnected!' });
});
socket.on('response', function (data) {
console.log(data.age)
});
});
</script>
</head>
<body>
<h1>德玛西亚</h1>
</body>
</html>
# 后端实现
Flask-SocketIO使Flask应用程序可以访问客户端和服务器之间的低延迟双向通信。
# 安装
pip install flask-socketio
# send 和 emit区别
send
发送的是无命名的数据,而emit
是发送有命名的数据,个人建议是emit
# 简单使用
on
是注册接收前端消息的方法,message
是指接收的信息的名称,和前端对应。namespace
是指一类的消息,和前端对应。emit
是指向前端发送消息,对应的消息的名称、数据和namespace
。
默认的两个事件,connect
和disconnect
,当websocket连接成功和失败时,自动触发这两个事件。
from flask import Flask, render_template
from flask_socketio import SocketIO
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
@app.route('/')
def index():
return render_template('index.html')
@socketio.on('message', namespace="/wechat")
def handle_message(message):
print('received message: ' message['data'])
socketio.emit("response", {'age': 18}, namespace="/wechat")
@socketio.on('connect', namespace="/wechat")
def connect():
print("connect..")
@socketio.on('disconnect', namespace="/wechat")
def connect():
print("disconnect...")
if __name__ == '__main__':
socketio.run(app, port=8080)
# 基于类的使用
上面都是基于方法使用,个人感觉如果操作较多的情况,比较凌乱,使用类去管理会整齐和方便很多。
服务器收到的任何事件都会被分配到一个名为带有on_前缀的事件名称的方法。
这个案例和上面基于方法是一样的,但是更加方便管理了,每个class管理一个namespace。
代码语言:javascript复制class MyCustomNamespace(Namespace):
def on_connect(self):
print("连接..")
def on_disconnect(self):
print("关闭连接")
def on_message(self, data):
print('received message: ' data['data'])
self.emit("response", {'age': 18})
socketio.on_namespace(MyCustomNamespace("/wechat"))