Flask-[实现websocket]-(2): flask-socketio文档学习

一、简单项目的构建

flask_websocket

        |---static

                |---js

                        |---jquery-3.7.0.min.js

                        |---socket.io_4.3.1.js

        |---templates

                |---home

                        |---group_chat.html

                        |---index.html

        |---app.py

1.1、python环境

python3.9.0

1.2、依赖包

Flask==2.1.0
eventlet==0.33.3     #使用这个性能会最优
Flask-SocketIO==5.3.4


1.3、js文件下载

https://code.jquery.com/jquery-3.7.0.min.js

https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.3.1/socket.io.min.js

 

1.4、app.py 配置

from flask import Flask, render_template
from flask_socketio import SocketIOapp = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app,cors_allowed_origins='*')if __name__ == '__main__':socketio.run(app)

二、官方文档的学习

2.1、namespace:名称空间

概述:名称空间,事件函数在处理请求时,只会处理相同名称空间的websocket请求。跟路由分发很像,把处理请求范围缩小在指定区域中。一般用在不同功能,大方向的不同功能。

功能:Flask-SocketIO 还支持 SocketIO 命名空间,允许客户端在同一个物理套接字上多路复用多个独立连接。

1、如果不设置名称空间,是由默认的名称空间的,就是\

2、在fbv使用时,可以不指定默认的名称空间,在cbv使用时,必须指定名称空间

2.1.1、后端简单的例子:

1、使用默认的全局名称空间

@socketio.on('message')
def handle_message(data):#data: 前端发送过来的数据print('received message: ' + data)

2、定义了名称空间的

@socketio.on('message',namespace='/default')
def namespace_message(data):''':param data:前端发起websocket,传递给服务端的数据 :return: '''print('接收到前端发送过来的数据:',data)

虽然这两个事件函数,监听的是同一个事件,但是它们的名称空间不一样,所以数据的收发不会混乱。

2.1.1、前端js例子

1、js连接默认的名称空间

<!DOCTYPE html>
<html>
<head><script src="/static/js/socket.io_4.3.1.js"></script><script src="/static/js/jquery-3.7.0.min.js"></script><script type="text/javascript">var socket = io('http://'+document.domain+':'+location.port);// 1、监听服务器端,给message事件的响应socket.on('message', function(message) {// 处理从服务器接收到的响应数alert(message)});//3、 发送'message'事件给服务器dfunction sendMessage() {var message = {"type":"user","id":1};//向后端获取id=1的用户的数据socket.emit('message',message); //可以直接返回字典等数据}</script>
</head>
<body><div id="show"></div><button onclick="sendMessage()">Send Message</button></body>
</html>

2、js连接指定的名称空间

<!DOCTYPE html>
<html>
<head><script src="/static/js/socket.io_4.3.1.js"></script><script src="/static/js/jquery-3.7.0.min.js"></script><script type="text/javascript">const namespace = '/default';var socket = io('http://'+document.domain+':'+location.port+namespace);// 1、监听服务器端,给message事件的响应socket.on('message', function(message) {// 处理从服务器接收到的响应数alert(message)});//3、 发送'message'事件给服务器dfunction sendMessage() {var message = {"type":"user","id":1};//向后端获取id=1的用户的数据socket.emit('message',message); //可以直接返回字典等数据}</script>
</head>
<body><div id="show"></div><button onclick="sendMessage()">Send Message</button></body>
</html>

2.2、事件

概述:在名称空间下,就开始匹配事件名,最终是基于事件名进行消息的收发的。事件名可以找到指定的函数来处理这个事件请求的。还是跟路由分发类似,先找到一个大范围,再从这个范围中找指定的某个路由,将请求交给路由对应的函数处理。

2.2.1、自带的4个事件

1、connect   事件

        用来控制是否允许客户端建立连接的,一般会在这里验证用户的token,token验证通过才允许连接;或群聊中显示谁进入群聊了。

发起连接时,怎么携带上数据:

<script type="application/javascript">//1、发起连接const namespace = '/test'const socket = io('http://'+document.domain+':'+location.port+namespace,{query:{'token':'123456','group':group,'name':name}});
</script>
@socketio.on('connect',namespace='/chat')
def chat_connect():'''控制群里用户进入群连接:return:'''token = request.args.get('token')name = request.args.get('name')group = request.args.get('group')print('发起连接时携带的数据:',request.args)if token:join_room(group)emit('group_recv',{'name':name,'msg':f'进入’{group}‘群聊','type':'connect'},room=group)else:return False

2、disconnect   事件

        一般是用于统计活着的连接数,或者群聊中显示谁退出群聊。

3、message 事件

        可以传递字典、字符串等数据结构。

4、json 事件

        可以传递字典、字符串等数据结构。在使用过程中。

json和message事件,好像在使用上没有区别,看文档也没有看出啥不同之处。

2.2.2、事件函数的写法

1、显示指定事件名

使用默认的名称空间时:

@socketio.on('my_event')
def handle_my_custom_event(json):print('received json: ' + str(json))

指定名称空间时:

@socketio.on('my_event',namespace='/test')
def handle_my_custom_event(json):print('received json: ' + str(json))

2、使用函数名作为事件名

使用默认的名称空间时:

@socketio.event
def my_custom_event(data):print('received data: ',data)

指定名称空间时:

@socketio.event(namespace='/test')
def my_custom_event(data):print('received data: ',data)

2.2.3、自定义事件名称

自定义的事件名称,message、json、connect、disconnect是保留名称,不能用于已命名事件。

2.3、消息发送

from flask_socketio import send,emit

1、send  : 不能指定事件名,默认指定message事件,不能改。

传递的参数:第一个是发送的数据,namespace=‘/名称空间’, broadcast=True 采用广播

2、emit:需要指定事件名,可以指定自定义的事件。

传递的参数:事件名称、传递发送的数据,namespace=‘/名称空间’, broadcast=True 采用广播

在普通的视图函数中使用:(在事件函数中使用方法一样)

@app.route('/test/push')
def test_push():emit('json',{'code':200,'msg':'使用emit来主动推送广播'},namespace='/test',broadcast=True)send({'code':200,'msg':'使用send来主动推送广播'},namespace='/test',broadcast=True)return jsonify({"code":200,'msg':'ok'})

注意:send和emit必须在 socketio.on 装饰的事件函数中使用,需要使用到request.sid ,在普通的视图函数中无法这两个方法。

3、socketio.send() 和socketio.emit()  

参数:不能传递broadcast=True,其他与send和emit没有区别。

功能:发送的消息是广播消息。

socketio.send() 是给message事件推送消息,而且推送的是广播消息。

socketio.emit() 需要传递事件名称,推送是也是广播消息。

注意:这个两个方法一般在视图函数中使用,给系统中同一个名称空间下的事件名广播消息。

2.4、广播

广播:广播的范围是同一个名称空间下的同一个事件进行消息广播。

from flask_socketio import send,emit

使用这两个时,要实现广播功能需要添加参数,broadcast=True。

from flask_socketio import SocketIO

socketio=SocketIO(app)

socketio.send('data'), 给message事件广播消息。

socketio.emit('xxx','data') , 给xxx事件广播消息。

2.5、房间号

概述:要实现群聊功能,需要房间的功能,将连接添加到某个房间中,这些连接就在一个房间中。一个连接向房间中发送消息,房间中的所有连接都会接收到该消息。房间很像广播,只是房间的把消息的范围限定在房间中(名称空间、事件名称、房间号都一样),而广播,只要名称空间和事件名一样就会接收到,消息范围会更大。

from flask_socketio import join_room,leave_room

join_room : 加入房间

leave_room: 退出房间

官方文档的例子:

1、建立连接后,基于join事件,把连接添加到某个房间中

2、建立连接后,基于leave事件,把连接从某个房间中移除

from flask_socketio import join_room, leave_room@socketio.on('join')
def on_join(data):username = data['username']room = data['room']join_room(room)send(username + ' has entered the room.', to=room)@socketio.on('leave')
def on_leave(data):username = data['username']room = data['room']leave_room(room)send(username + ' has left the room.', to=room)

在使用时,加上名称空间会更容易区分功能。

from flask_socketio import join_room, leave_room@socketio.on('join',namespace='/chat')
def on_join(data):username = data['username']room = data['room']join_room(room)send(username + ' has entered the room.', to=room)@socketio.on('leave',namespace='/chat')
def on_leave(data):username = data['username']room = data['room']leave_room(room)send(username + ' has left the room.', to=room)@socketio.on('group',namespace='/chat')
def handle_group(data):''':param data: 用户在群聊中发送消息:return:'''print('chat群里发消息:',data)group = data.get('group')msg = data.get('msg')name = data.get('name')ret_data = {'msg':msg,'name':name,'type':'data'}emit('group_recv',ret_data,room=group)

2.6、CBV的写法

概述:使用CBV的写法 ,就必须传递上namespace,即使是默认的全局名称空间,也得传递'/' .

2.6.1、官方例子

from flask_socketio import Namespace, emitclass MyCustomNamespace(Namespace):def on_connect(self):#方法名去掉on_,剩下的就是事件名称,connect事件passdef on_disconnect(self):#方法名去掉on_,剩下的就是事件名称,disconnect事件passdef on_my_event(self, data):#方法名去掉on_,剩下的就是事件名称,my_event事件emit('my_response', data)#注册该消费类,类似注册路由一样
socketio.on_namespace(MyCustomNamespace('/test'))

2.6.2、官方例子与js结合

html文件

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>群聊</title><script type="application/javascript" src="/static/js/jquery-3.7.0.min.js"></script><script type="application/javascript" src="/static/js/socket.io_4.3.1.js"></script><script type="application/javascript">//传递给模板的数据,转成python数据结构const data = {{ data|tojson }};const group = 'group1'; //群名const name = 'lhz';//当前用户名//1、发起连接const socket = io('http://'+document.domain+':'+location.port+'/cbv',{query:{'token':'123456','group':group,'name':name}});//2、监听my_event事件,服务端发送数据给my_event事件socket.on('my_event',function (data) {console.log('my_event事件监听到')console.log(data)});//3、前端主动发my_event事件到服务端function sendDataFunc() {const $sendData = $('#sendDataId');socket.emit('my_event',{'group':group,'msg':$sendData.val(),'name':name});}</script>
</head>
<body>{#1、展示群聊的消息#}
<div id="showDataId"></div>{#2、发送消息的输入框#}
<div><input id="sendDataId" type="text"><p><input type="button" value="发送给my_event事件" onclick="sendDataFunc()"></p>
</div></body>
</html>

cbv例子:

@app.route('/cbv')
def cbv_html():return render_template('test/test_cbv.html',data={'group':'123','name':'lhz'})class MyCustomNamespace(Namespace):def on_connect(self):# 方法名去掉on_,剩下的就是事件名称,connect事件print(request.args,'发起连接时携带的数据')def on_disconnect(self):# 方法名去掉on_,剩下的就是事件名称,disconnect事件print('退出连接')def on_my_event(self, data):# 方法名去掉on_,剩下的就是事件名称,my_event事件print('前端给my_event事件发送的消息',data)emit('my_event', {'code':200,'msg':'后端接收到并返回了','data':data.get('msg')})# 注册该消费类,类似注册路由一样
socketio.on_namespace(MyCustomNamespace('/cbv'))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/143042.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

网络通信(套接字通信)(C/C++)

1.网络编程必知概念 1.广域网和局域网 广域网:又称外网、公网。是连接不同地区局域网或城域网进行计算机通信的远程公共网络。 局域网:在一定的通信范围内,有很个多计算机组成的私有网络就叫局域网。(这些计算机相互之间是可以通信的,但是不能直接访问外网(可以通过网线…

虹科方案 | LIN/CAN总线汽车零部件测试方案

文章目录 摘要一、汽车零部件测试的重要性&#xff1f;二、虹科的测试仿真工具如何在汽车零部件测试展露头角&#xff1f;三、应用场景**应用场景1&#xff1a;方向盘开关的功能测试****应用场景2&#xff1a;各类型电机的控制测试****应用场景3&#xff1a;RGB氛围灯的功能测试…

CISSP,你值得拥有(我的学习之路)

&#xff08;只分享三点&#xff1a;怎么学、怎么练、怎么考。&#xff09; 我为啥去考CISSP 我是个在信安行业摸爬滚打将近20年的老油条&#xff0c;知道CISSP这个认证是很早前的事情了&#xff0c;但一直以来都觉得它有点难&#xff0c;加上人又懒得要命&#xff0c;也就始…

安装elasticsearch

1.部署单点es 1.1.创建网络 因为我们还需要部署kibana容器,因此需要让es和kibana容器互联。这里先创建一个网络: docker network create es-net 1.2.加载镜像 这里我们采用elasticsearch的7.12.1版本的镜像,这个镜像体积非常大,接近1G。不建议大家自己pull。 课前资料提…

用selenium和xpath定位元素并获取属性值以及str字符型转json型

页面html如图所示&#xff1a; 要使用xpath定位这个div元素&#xff0c;并且获取其属性data-config的内容值。 from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.options import Optionshost127.0.0.1 port10808 …

Serlet API详解

目录 一、HttpServlet 1.1 处理doGet请求 1.2 处理doPost请求 二、HttpServletRequest 2.1 核心方法 三、HttpServletRespons 3.1 核心方法 一、HttpServlet 在编写Servlet代码的时候&#xff0c;首先第一步要做的就是继承HttpServlet类&#xff0c;并重写其中的某些方法 核心…

最新ChatGPT网站系统源码+支持GPT4.0+支持AI绘画Midjourney绘画+支持国内全AI模型

一、SparkAI创作系统 SparkAi系统是基于很火的GPT提问进行开发的Ai智能问答系统。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT系统&#xff1f;小编这里写一个详细图文教程吧&a…

前端知识总结

在前端开发中&#xff0c;y x是一种常见的自增运算符的使用方式。它表示将变量x的值自增1&#xff0c;并将自增后的值赋给变量y。 具体来说&#xff0c;x是一种后缀自增运算符&#xff0c;表示将变量x的值自增1。而y x则是将自增前的值赋给变量y。这意味着在执行y x之后&am…

文件夹无法删除怎么办?4种实用方法,轻松解决

在日常使用电脑时&#xff0c;有时候会碰到无法删除文件夹的情况&#xff0c;这可能会带来一些困扰。如果你想删除一个文件夹却发现无法删除&#xff0c;不必担心&#xff0c;其实是有解决方法的。下面一起来了解下文件夹不能删除的原因以及解决方法吧。 文件夹为什么不能删除…

编程每日一练(多语言实现):判断偶数

文章目录 一、实例描述二、技术要点三、代码实现3.1 C 语言实现3.2 Python 语言实现3.3 Java 语言实现 一、实例描述 利用单条件单分支选择语句判断输入的一个整数 是否是偶数。 运行程序&#xff0c;输入一个 整数18&#xff0c; 然后按回车键&#xff0c;将提示该数字是偶数…

深入理解React中fiber

一、前言 Fiber是对React核心算法的重写&#xff0c;Fiber是React内部定义的一种数据结构&#xff0c;将更新渲染耗时长的大任务&#xff0c;分为许多的小片。Fiber节点保存啦组件需要更新的状态和副作用&#xff0c;一个Fiber代表一个工作单元。 二、Fiber在React做了什么 …

【文末送书】用Chat GPT轻松玩转机器学习与深度学习

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和技术。关…

华南理工大学电子与信息学院23年预推免复试面试经验贴

运气较好&#xff0c;复试分数90.24&#xff0c;电科学硕分数线84、信通83、专硕电子与信息74. 面试流程&#xff1a; 1&#xff1a;5min ppt的介绍。其中前2min用英语简要介绍基本信息&#xff0c;后3min可用英语也可用中文 介绍具体项目信息如大创、科研、竞赛等&#xff08…

Android 遍历界面所有的View

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、商业变现、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览三、实践四、 推荐阅读 一、导读 我们…

linux使用操作[2]

文章目录 版权声明网络传输ping命令wget命令curl命令端口linux端口端口命令和工具 进程管理查看进程关闭进程 主机状态top命令内容详解磁盘信息监控 版权声明 本博客的内容基于我个人学习黑马程序员课程的学习笔记整理而成。我特此声明&#xff0c;所有版权属于黑马程序员或相…

MySQL - 全表分组后,获取组内排序首条数据信息

性能 不详!!! 不详!!! 不详!!! 请谨慎使用!!!环境 MySQL服务: 8.0版本;思路 使用8.0版本的新函数特性: row_number(): 序号函数; 顾名思义, 就是给每组中的元素从1开始按顺序加上序号;over(): 其中两个语法如下 partition: 按某字段分组;order by: 按某字段排序;注意: 两函数详…

算法通过村第十关-快排|白银笔记|快排实战

一个程序员一生中可能会邂逅各种各样的算法&#xff0c;但总有那么几种&#xff0c;是作为一个程序员一定会遇见且大概率需要掌握的算法。今天就来聊聊这些十分重要的“必抓&#xff01;”算法吧~ 文章目录 前言数组第K大总结 前言 这是快排中的经典算法题&#xff0c;但是很多…

数据库:Hive转Presto(一)

本人因为工作原因&#xff0c;经常使用hive以及presto&#xff0c;一般是编写hive完成工作&#xff0c;服务器原因&#xff0c;presto会跑的更快一些&#xff0c;所以工作的时候会使用presto验证结果&#xff0c;所以就要频繁hive转presto&#xff0c;为了方便&#xff0c;我用…

php函数usort使用方法

在 PHP 中&#xff0c;usort() 函数用于对数组进行排序&#xff0c;它允许你使用自定义的比较函数来确定元素的顺序。以下是 usort() 函数的使用方法&#xff1a; usort(array &$array, callable $cmp_function): bool参数说明&#xff1a; $array&#xff1a;要排序的数…

【新版】系统架构设计师 - 案例分析 - 架构设计<Web架构>

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 文章目录 架构 - 案例分析 - 架构设计&#xff1c;Web架构&#xff1e;Web架构知识点单台机器 到 数据库与Web服务器分离应用服务器集群负载均衡负载均衡技术静态与动态算法Session共享机制有状态与无状态 持久化技…