什么是websocket

WebSocket是一种网络通讯协议,
与HTTP不同的是,WebSocket提供全双工通信。
也就是说,传统的方式,只有当客户端发起请求后,服务器端才会发送数据,
而WebSocket可以让服务器主动发送数据给客户端,它是服务器推送技术的一种。

数据通信中,数据在线路上的传送方式可以分为

  • 单工通信
  • 半双工通信
  • 全双工通信

单工通信信道是单向信道,发送端和接收端的身份是固定的,发送端只能发送信息,不能接收信息;接收端只能接收信息,不能发送信息,数据信号仅从一端传送到另一端,即信息流是单方向的。

半双工通信,即Half-duplex
Communication。这种通信方式可以实现双向的通信,但不能在两个方向上同时进行,必须轮流交替地进行。也就是说,通信信道的每一段都可以是发送端,也可以是接收端。但同一时刻里,信息只能有一个传输方向。如日常生活中的例子有步话机通信,半双工对讲机(对讲模式可分为单工通信、半双工通信和全双工通信)等。

全双工(Full Duplex)是
在微处理器与外围设备之间采用发送线和接受线各自独立的方法,可以使数据在两个方向上同时进行传送操作。指在发送数据的同时也能够接收数据,两者同步进行,这好像我们平时打电话一样,说话的同时也能够听到对方的声音。

HTTP协议各版本差异以及图示

下图是WebSocket和HTTP的区别

在这里插入图片描述

什么是Socket.IO

socket.io就是基于websocket封装的一个库,主要特点是能够进行实时的双向通讯,主要应用场景有实时的聊天,数据实时分析,数据传输,文件协同合作。

WebSockets与Socket.io主要特征对比

在这里插入图片描述

Flask-SocketIO是作为 Flask 扩展的 Socket.IO 服务器端协议的实现。

pip install flask-socketio

参考网址:

https://flask-socketio.readthedocs.io/en/latest/api.html
https://blog.csdn.net/y472360651/article/details/116545273
https://blog.csdn.net/ieeso/article/details/105040207
https://xugaoxiang.com/2020/10/08/flask-19-socketio/

send 和 emit区别
send发送的是无命名的数据,而emit是发送有命名的数据,个人建议是emit

简单使用
on是注册接收前端消息的方法,message是指接收的信息的名称,和前端对应。
namespace是指一类的消息,和前端对应。
emit是指向前端发送消息,对应的消息的名称、数据和namespace。

默认的两个事件,connect和disconnect,当websocket连接成功和失败时,自动触发这两个事件。

namespace  命名空间
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>SocketIO Demo</title>
    <script type="text/javascript" src="//cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
    <script type="text/javascript" src="//cdn.bootcss.com/socket.io/3.1.2/socket.io.min.js"></script>
</head>
<body>

<h2>Demo of SocketIO</h2>
<div id="t"></div>
<script>
$(document).ready(function () {
    namespace = '/dcenter';
    var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace);
    socket.on('dcenter', function (res) {
        var t = res.data;
        if (t) {
            $("#t").append(t).append('<br/>');
        }

    });
});
</script>
</body>
</html>

在这里插入图片描述
上述兼容详细说明

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

# pip install flask-socketio
# Flask==2.1.1
# Flask-SocketIO==5.1.1
# greenlet==1.1.2
# Jinja2==3.1.1
# python-engineio==4.3.1
# python-socketio==5.5.2
# Werkzeug==2.1.1

app = Flask(__name__)
# app.config['SECRET_KEY'] = 'secret_key'

socketio = SocketIO()
socketio.init_app(app, cors_allowed_origins='*')
# socketio.init_app(app, cors_allowed_origins='http://localhost')

name_space = '/dcenter'

@app.route('/123')
def hello():
    # How can I send a WebSocket message from here?
    return 'Hello World!'


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

@app.route('/push')
def push_once():
    event_name = 'dcenter'
    broadcasted_data = {"type":"delete","user_id":"123","data":"1111111111111"}
    socketio.emit(event_name, broadcasted_data, broadcast=False, namespace=name_space)
    return 'done!'

@socketio.on('connect', namespace=name_space)
def connected_msg():
    print('client connected.')

@socketio.on('disconnect', namespace=name_space)
def disconnect_msg():
    print('client disconnected.')

@socketio.on('my_event', namespace=name_space)
def mtest_message(message):
    print(message)
    emit('my_response',
         {'data': message['data'], 'count': 1})

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

部署
Flask-SocketIO 文档里有提到,Gunicorn 目前运行 Flask-SocketIO 程序时只能使用 1 个 worker:

Due to the limited load balancing algorithm used by gunicorn, it is not possible to use more than one worker process when using this web server. For that reason, all the examples above include the -w 1 option.

Flask-SocketIO

问题一
Flask-SocketIO 线程中已推送的,前端收不到

默认async_mode的模式是eventlet(协程)

修改如下:

socketio.init_app(app, cors_allowed_origins='*', async_mode="threading")

链接1

链接2

在这里插入图片描述
start_background_task

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐