Flask-SocketIO为Flask应用程序提供对客户端和服务器之间的低延迟双向通信的访问。客户端应用程序可以使用Javascript,C++,Java和Swift中任何SocketIO官方客户端和任何兼容客户端来建立与服务器的永久连接。

安装

pip install flask-socketio

依赖

Flask-SocketIO兼容Python2.7和Python3.3+,该软件的异步服务可以从以下三种选择中选择:

  • eventlet:高性能选项,支持长轮询和WebSocket传输
  • gevent:支持多种不同的配置。long-polling传输完全由gevent包支持,但与eventlet不同,gevent没有原生的WebSocket支持。为了增加对WebSocket的支持,目前有两种选择:安装gevent-websocket软件包会将WebSocket支持添加到gevent中,或者可以使用随WebSocket功能一起提供的uWSGI Web容器。gevent也是一项高性能选项,但略低于eventlet。
  • 基于Werkzeug的Flask开发服务器也可以使用,但需要注意的是它缺少其他两个选项的性能,所以它只能用于简化开发流程。该选项仅支持长轮询传输

该扩展根据安装的内容自动检测使用哪个异步框架,优先考虑eventlet,然后是gevent。对于gevent中的WebSocket支持,首选uWSGI,然后是gevent-websocket。如果既没有安装eventlet,也没有安装gevent,则使用Flask开发服务器。

如果使用多个进程,则进程使用消息队列服务来协调诸如广播等操作。受支持的队列包括:Redis、RabbitMQ和Kombu软件包支持的任何其他消息队列。

初始化

举个简单的栗子:

from flask import Flask
from flask_socketio import SocketIOapp = Flask(__name__)
app.config["SECRET_KEY"] = "secret!"
socketio = SocketIO(app)if __name__ == "__main__":socketio.run(app, host="0.0.0.0", port=5000)

init_app()初始化的样式也被支持。请注意Web服务器的启动方式,该socketIO.run()功能封装了Web服务器的启动并取代了app.run()标准的Flask开发服务器的启动。当我们的服务器程序启动了,相应的客户端程序必须提供一个页面加载SocketIO库:

<script type="text/javascript" src="http://cdn.bootcss.com/socket.io/1.5.1/socket.io.min.js"></script>
<script type="text/javascript" charset="utf-8">var socket = io.connect('http://localhost:5000');socket.on('connect', function() {socket.emit('my event', {"data": 'I\'m connected!'});});socket.on('my response',function(message){console.log(message)})
</script>

第一个路由

下面写一个简单的路由,使服务器与客户端进行连接:

from flask_socketio import emit@socketio.on("connect")
def handle_connect():print("server has connected")emit("my response", "server has connected")

下面再定义一个my event路由,接收客户端发送过来的消息:

from flask_socketio import emit@socketio.on("my event")
def handle_event(message):print("服务器已经接收到消息:" + message["data"])emit("my response", "服务器已经接收到消息:" + message["data"])

当客户端与服务器端进行相连时,服务器端将会先后打印如下信息:

server has connected
服务器已经接收到消息:I'm connected!

客户端将会先后打印如下信息:

server has connected
服务器已经接收到消息:I'm connected!

接收消息

使用SocketIO时,消息由双方作为事件接收。在客户端使用JavaScript回调。使用Flask-SocketIO时,服务器需要为这些时间注册处理程序,类似于视图函数处理路由的方式。

  • 未命名事件:对于客户端使用send发送的匿名消息,flask使用message来进行接收
    以下实例创建一个服务器端未命名事件处理程序:
@socketio.on('message')
def handle_message(message):print('接收到消息:' + message)
  • 自定义命名事件:flask可以自定义路由的名称,这样的路由称之为自定义命名事件
@socketio.on("my event")
def handle_event(arg1, arg2, arg3):print(arg1, arg2, arg3)

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

@socketio.on("my event",namespace="/test")
def handle_my_event(message):print("test", message)

有时我们还需要动态添加一些路由,很显然装饰器已经不符合我们的需求。我们还可以使用on_event方法:

def custom_func(message):print("custom", message)socketio.on_event("custom func", custom_func, namespace="/test")

客户端可以要求确认回复,用于确认收到他们的消息。从处理函数返回的任何值都将作为客户端的回调函数的参数传递给客户端:

@socketio.on("message")
def handle_message(message):return "已经收到了消息:" + str(message)

发送消息

在第一个路由中,我们使用了emit()函数来发送消息给客户端,并且在上面的接收消息中知道客户端可以使用send来发送未命名事件消息,既然客户端可以使用send函数,那么服务器端当然也可以。所以,我们可以使用emit()send()两种函数来发送消息给客户端。值得注意的是:send()emit()的分别在于分别用于未命名事件与自定义命名事件。

举个简单的发送消息的栗子:

from flask_socketio import emit, send@socketio.on('message')
def handle_message(message):send(message)@socketio.on('my event')
def handle_event(event):emit('my response', event)

注意的是:对于服务器使用send发送的匿名消息,客户端同样使用用message来进行接收

当有命名空间时,send()emit()默认使用传入消息的命名空间,当然也可以使用namespace参数来指定不同的命名空间:

@socketio.on('message')
def handle_message(message):send(message, namespace='/test')

如果需要发送一个包含多个参数的时间,请发送一个元组:

@socketio.on('my event')
def handle_message(message):emit('my response', (message, "aa"))

广播

SocketIO的另一个有用的功能是广播消息。Flask-SocketIO也支持这个特性,在send()emit()函数中设置可选参数broadcast=True即可:

@socketio.on('my event')
def handle_my_event(data):emit('my response', data, broadcast=True)

当使用broadcast=True的情况下发送消息,连接到命名空间的所有客户端都将收到该消息。当不使用命名空间时,连接到全局名称的客户端将收到此消息。注意,广播消息不会回调

房间

对于许多应用程序来说,有必要将用户分组到可以一起处理的子集中。最好的栗子就是具有多个房间的聊天应用,用户可以从他们所在的房间接收消息,但不能从其他用户所在的其他房间接收消息。Flask-SocketIO通过join_room()leave_room()方法来支持房间的功能

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

所有的客户端在连接时都会分配一个房间,以连接的会话ID命名,会话ID可以通过request.sid获取。当我们想给指定客户端发送消息时,我们可以emit()send()函数,将会话ID传递到函数中的to参数里面就可以实现。当我们想给房间里的每个客户端都发送一条一样的消息时,我们可以将房间ID传递到room参数,或to参数里面就可以实现了

连接与断开连接

Flask-SocketIO还分派连接和断开连接事件,如下:

@socketio.on('connect')
def on_connect():pass@socketio.on('disconnect')
def on_disconnect():pass

连接事件处理程序可以返回False来拒绝连接,也可以引发ConnectRefusedError。如下,如果是未认证的,那么将拒绝连接!

from flask_socketio import ConnectRefusedError@socketio.on('connect')
def on_connect():if not self.authenticate(request.args):raise ConnectionRefusedError('unauthorized!')

基于类的命名空间

作为上述基于装饰器的事件处理程序的替代,可以将属于命名空间的事件处理程序创建为类的方法。flask_socketio.Namespace被设置为基类来创建基于类的命名空间:

from socketio import Namespaceclass MyCustomNamespace(Namespace):def on_connect(self):emit('connect_success', {'msg': 'connect success'})def on_disconnect(self):passdef on_edit(self, data):article_id = data.get('article_id')join_room(article_id)emit('edit_success', {'msg': f'{article_id} edit success'})socketio.on_namespace(MyCustomNamespace('/'))

使用基于类的命名空间时,服务器接收到的任何事件都被发送到一个以on_前缀作为事件名的方法。例如,事件“my_event”将由一个名为“on_my_event”的方法处理。如果接收的事件在命名空间类中没有定义相应的方法,则忽略该事件。

更多Flask-SocketIO的用法,请看https://flask-socketio.readthedocs.io/en/latest/

自此,Over~~~

Flask-SocketIO的使用相关推荐

  1. Nginx + uWSGI + flask + socketio 部署解决方案

    Nginx + uWSGI + flask + socketio 部署解决方案 参考文章: (1)Nginx + uWSGI + flask + socketio 部署解决方案 (2)https:// ...

  2. flask+socketio+echarts3 服务器监控程序(基于后端数据推送)

    本文地址:http://www.cnblogs.com/hhh5460/p/7397006.html 说明 以前的那个例子的思路是后端监控数据存入数据库:前端ajax定时查询数据库. 这几天在看web ...

  3. python程序发布 ubuntu_在ubuntu16.04的虚拟环境中运行Python程序作为服务

    我正在尝试让一个Flask+SocketIO应用程序作为一个服务在ubuntu16.04上运行,在一个虚拟环境中.我的服务器每天凌晨3点重新启动(超出我的控制范围),所以我需要它在启动时自动启动.在 ...

  4. 什么是WebSocket,以及如何在Python中使用它?

    什么是WebSocket? (What is WebSocket?) WebSocket is a communications protocol which provides a full-dupl ...

  5. ubuntu18.04 ros 使用anaconda创建虚拟环境 python3.7安装 opencv-3.4.6,TensorFlow安装,notebook

    使用anaconda创建虚拟环境opencv-3.4.6安装TensorFlow安装 ps: ros系统python2.7与 python3.7安装 OpenCV有冲突所以使用anaconda创建虚拟 ...

  6. 人脸自收集数据集辅助制作工具——多人在线协同标注系统

    综述 我们在进行人脸属性识别深度学习算法研究过程中除了使用开源带标签的数据以外,都会根据具体使用场景与需求用到大量自收集的图像数据(开源/爬虫/自拍等),然这些数据一般是没有人脸对应属性标注标签的.而 ...

  7. 部分算法与对应代码整理(R、Python)

    目录 1. 图像.人脸.OCR.语音相关算法整理 2. 机器学习与深度学习相关的R与Python库 (1)R General-Purpose Machine Learning Data Manipul ...

  8. Cozmo机器人使用

    原文链接: 目录 1. 入坑始末 2. 启动 Cozmo 3. 开始鼓捣 4. 开发环境搭建--Cozmo Explorer Tool 安装 4.1. 下载 4.2. 安装依赖 4.2.1. Cozm ...

  9. [原创]智能可编程机器人—— Cozmo 入门及开发指南

    目录 1. 入坑始末 2. 启动 Cozmo 4.1. 下载 4.2. 安装依赖 4.2.1. Cozmo SDK 安装 4.2.2. 安装 Pillow 模块 4.2.3. 安装 Flask 模块 ...

  10. 用Python编程控制Cozmo机器人(Python环境搭建和工具准备)

    在b站看了介绍视频,这个小玩意儿可以说相当炫酷了 这是它的官网 准备给Brother买的小玩具Cozmo,官方提供了SDK用于Python编程,于是自己也研究一下,慢慢更新这篇文章,方便各位想编程的. ...

最新文章

  1. R语言数据结构之因子
  2. 七天学习计划_c#_[1]泛型类(还有六天,明天继续写!)
  3. 南工计算机调剂,南京工业大学2021年硕士研究生调剂公告
  4. 【译】Go语言声明语法
  5. 30万奖金海华AI挑战赛 | 用机器挑战中文阅读理解
  6. spark 广播变量大数据_Spark基础知识(三)--- Spark的广播变量和累加器
  7. sts-bundle的使用_使用WS-Trust / STS采样器扩展JMeter
  8. NYOJ90 整数划分(经典递归和dp)
  9. redis实践的一点思路,关于支付回调
  10. python 发邮件_Python发邮件告别smtplib,迎接zmail
  11. mysql binlog查看工具_数据同步工具otter(一)谈谈binlog和canal
  12. 用DirectX Audio和DirectShow播放声音和音乐(3)
  13. JavaScript 优先队列
  14. 国际象棋渲染测试软件,C4D结合Octane Render渲染器制作三维国际象棋建模渲染教程 含中英文字幕...
  15. bt和wifi的共存
  16. mir显示服务器,The Legend Of Mir 服务器程序安装说明(图片)
  17. gif透明背景动画_在找gif制作app?分享一个GIF制作神器,视频、图片通通可以变GIF...
  18. 6.1 CUDA: pinned memory固定存储
  19. PMP学习笔记20161130
  20. 如何查看计算机管理员用户名和密码,Administrator密码怎么找回教程

热门文章

  1. linux输入数字切换浏览器tab,js监听浏览器tab窗口切换
  2. 国内使用chatgpt便捷方式-CSDN内部
  3. 国外有哪些比较好的电子技术方面的网站论坛推荐? - 知乎
  4. Infrared Small Target Detection 2021
  5. 支持服务器系统什么意思,服务器系统支持
  6. RabbitMQ图文详解 | MQ_SpringAMQP | 系统性学习 | 无知的我费曼笔记
  7. 企业级GIS系统架构介绍——总览
  8. Samplitude pro x4完美汉化破解版|Samplitude pro x4 64位完美汉化破解版(附汉化包)下载 v15.0.1.139
  9. C语言怎么实现多个值输出?
  10. 系统软件开发基础知识