我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Flask使用SocketIO实现WebSocket与Vue进行实时推送

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Flask使用SocketIO实现WebSocket与Vue进行实时推送

前言

本文旨在记录使用Flask框架过程中与前端Vue对接过程中,存在WebSocket总是连接失败导致前端取不到数据的问题。以及在使用WebSocket相关功能的库包gevent-websocket之后,导致运行Flask项目之后,控制台没有显示running on 127.0.0.1:5000 问题、以及没有输出log日志记录的问题、以及总是报错Websocket connection to‘ws://127.0.0.1:5000/socket.io/?EIO=4&transport=websocket’failed:Error during Websocket handshake:Unexpected response code:400’的问题!

如下图所示:只有三行控制台输出的记录、总是报错(该错在网上没有解决方法)等。

技术选型:前端Vue、后端Flask。

核心问题

需要着重注意的是,Flask框架中有原生的Websocket写法,也有对Websocket封装之后的依赖包SocketIO写法,所以在进行与前端对接的过程中,需要与前端对接好接口标准。在本次项目中,后端最开始用的是封装好WebSocket后的socketio进行编写,而前端使用了原生的websocket-vue写法,导致一直对接不上,获取不到数据。以及所有的报错或者各种bug问题,笔者都推测是跟gevent-websocket这个包有关。

在前端更改为vue-socketio之后,成功解决对接失败问题。(也可以后端改用原生写法,总之两边需要同时使用一个标准。)前端Vue可以参考Vue的文档去看使用哪种写法即可。

Flask的原生WebSocket(flask-sockets)与封装SocketIO

Flask-Sockets和Flask-SocketIO之间的主要区别在于前者仅仅将WebSocket协议(通过使用gevent-websocket项目)进行包装,因此它只适用于原生支持WebSocket协议的浏览器,对于那些不支持WebSocket协议的较老的浏览器,就无法使用它了。

Flask-SocketIO则不同,它不仅实现了WebSocket协议,并且对于那些不支持WebSocket协议的旧版浏览器,使用它也能够实现相同的效果。新版旧版的浏览器都能使用他。可以这么理解,flask把websocket功能封装在了socketio这个新的包里面。

另一个区别是Flask-SocketIO实现了SocketIO Javascript库公开的消息传递协议。
而Flask-Sockets只是实现通信通道,发送的是完全取决于应用程序。

1、Flask-SocketIO(封装写法)

使用SocketIO之前需要导入该包,即pip install flask-socketio。也可以直接在代码中import该包中的两个功能。
即:from flask_socketio import SocketIO, emit。

下面是服务端代码:(关于如何在实战中应用,可以看笔者上一篇关于flask博客中的代码实现,大致思路是使用线程)

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

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

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

@socketio.on('my event', namespace='/test')
def test_message(message):
    emit('my response', {'data': message['data']})

@socketio.on('my broadcast event', namespace='/test')
def test_message(message):
    emit('my response', {'data': message['data']}, broadcast=True)

@socketio.on('connect', namespace='/test')
def test_connect():
    emit('my response', {'data': 'Connected'})

@socketio.on('disconnect', namespace='/test')
def test_disconnect():
    print('Client disconnected')
 


if __name__ == '__main__':
    socketio.run(app)

而对于js来说,客户端代码十分简单,直接上代码:(注意是socketio的标准)

$(document).ready(function(){
    var socket = io.connect('http://' + document.domain + ':' + location.port + '/test');
    //注意如果使用var socket = io.connect(location.protocol + ‘//' + document.domain.....的写法,这里的protocol是http协议,而不是走的是ws,笔者推测是对ws进行了封装,导致最终走的是http协议。
    //上面代码中的/test 就是namespace
    
    socket.on('my response', function(msg) {
        $('#log').append('<p>Received: ' + msg.data + '</p>');
    });.
    
    $('form#emit').submit(function(event) {
        socket.emit('my event', {data: $('#emit_data').val()});
        return false;
    });
    
    $('form#broadcast').submit(function(event) {
        socket.emit('my broadcast event', {data: $('#broadcast_data').val()});
        return false;
    });
});

2、Flask-Sockets(原生Websocket写法)

服务端:

from flask import Flask
from flask_sockets import Sockets
import datetime
import time
import random

app = Flask(__name__)
sockets = Sockets(app)

@sockets.route('/echo')
def echo_socket(ws):
    while not ws.closed:
        now = datetime.datetime.now().isoformat() + 'Z'
        ws.send(now)  #发送数据
        time.sleep(1)

@app.route('/')
def hello():
    return 'Hello World!'

if __name__ == "__main__":
    from gevent import pywsgi
    from geventwebsocket.handler import WebSocketHandler
    server = pywsgi.WSGIServer(('', 5000), app, handler_class=WebSocketHandler)
    print('server start')
    server.serve_forever()

客户端代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script class="lazy" data-src="https://cdn.bootcss.com/jquery/3.2.0/jquery.js"></script>
</head>
<body>
    <div id="time" style="width: 300px;height: 50px;background-color: #0C0C0C;
    color: white;text-align: center;line-height: 50px;margin-left: 40%;font-size: 20px"></div>

    <script>
            var ws = new WebSocket("ws://127.0.0.1:5000/echo");  #连接server
			//这是websocket的前端原生写法,直接连接ws。
            ws.onmessage = function (event) {
                content = document.createTextNode(event.data); # 接收数据
                $("#time").html(content);

            };

    </script>
    </body>
</html>

3、Bug 1:控制台输出没有Running on 127.0.0.1以及没有输出日志

在安装了gevent-websocket的这个包之后,会顺带安装gevent这个包,需要注意的是,gevent这个包会导致项目运行之后,控制台不会输出running on这个bug和 没有Log输出日志的bug。

经过笔者查证之后,发现是gevent-websocket这个包太老了,2017年的就已经停止更新了。所以这个包如果使用的话,会顺带导致一些对于新版本的Flask兼容性问题,所以导致了控制台的上述两个Bug存在。

解决方案:删掉gevent、gevent-websocket这两个包,可以下载 simple-websocket这个包来替代这两个包完成功能开发。

解决之后,控制台可以正常显示了。

4、Bug 2:显示连接错误。

在连接错误之后,推测这种报4的错误(网上全是3的错误),应该是没有安装gevent-websocket这个包,但是安装了之后又会造成第一类bug,所以可以直接安装simple-websocket这个依赖包。

参考文章:https://www.jb51.net/article/250776.htm

到此这篇关于Flask使用SocketIO实现WebSocket与Vue进行实时推送的文章就介绍到这了,更多相关Flask Vue 实时推送内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Flask使用SocketIO实现WebSocket与Vue进行实时推送

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

使用php开发Websocket,实现实时推送功能

标题:使用PHP开发Websocket,实现实时推送功能Websocket是一种基于TCP协议的通信协议,在Web开发中,可以使用Websocket实现实时推送功能,以实现实时通信或实时更新数据的需求。在本文中,我们将使用PHP语言开发We
使用php开发Websocket,实现实时推送功能
2023-12-09

在Spring boot项目中使用 mybatis 与Vue实现对数据进行增删改查操作

在Spring boot项目中使用 mybatis 与Vue实现对数据进行增删改查操作?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。pom文件
2023-05-31

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录