Flask使用flask_socketio实现websocket

谭彦
2023-12-01

下面是案例,是我自己用来测试使用的,可以直接运行的。详细的使用请看官网

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

默认的两个事件,connectdisconnect,当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。


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"))

欢迎关注,互相学习,共同进步~

我的个人博客

我的微信公众号:编程黑洞

 类似资料: