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. 《用于物联网的Arduino项目开发:实用案例解析》—— 3.4 小结
  2. AlphaCode到底强在哪儿?清华博士后十分钟视频详细解析
  3. 聚焦智造 共筑生态——“2016智能硬件生态圈品牌交流会”即将举行
  4. 设置Elasticsearch N-Gram字分析器的过程
  5. MATLAB | 解决打开延迟的情况
  6. 页面的主题标记--body
  7. ios13.5.1降级_高并发系统下的降级如何实现
  8. php 对象 堆栈,PHP对象在内存堆栈中的分配
  9. 写题10分钟,写题解8小时,一道头条面试题,真心难。
  10. 小D课堂 - 新版本微服务springcloud+Docker教程_3-04 SpringCloud微服务核心组件Eureka介绍和闭源后影响...
  11. 2021FME博客大赛 —— 基于FME的土地利用与夜光遥感数据综合统计
  12. linux两台服务器文件实时同步
  13. 理解Alpha-Beta 剪枝算法
  14. python游戏可以买什么书_游戏通关,电影看完,是时候用Python整理下电子书了
  15. Ubuntu下使用“Windows徽标键+R”打开终端
  16. 饥荒为啥显示专用服务器,饥荒服务器和专用服务器有什么区别 | 手游网游页游攻略大全...
  17. pythonttf字体反爬虫_利用Python采集起点中文网小说,并解决字体反爬的问题
  18. 推荐一些经典的炒股书籍
  19. python中多分支结构可以不用else吗_Python3基础 多分支结构 if-elif-else
  20. 国内首例!违反 GPL 协议致侵权,被判赔偿 50 万元

热门文章

  1. Android平台蓝牙相关名词缩写
  2. 论文查重参考文献算不算?
  3. BLUESIGN认证辅导,bluesign system管理输入,采取哪些负责任的行动
  4. idmp计算任务shell脚本创建路径全过程
  5. 关于使用listFile()遍历文件夹报空指针异常的问题
  6. 创维linux怎么连接wifi,创维酷开电视多屏互动Miracast玩法详解
  7. Spring源码分析(1) —— 从Xml的加载到解析
  8. wpf绘制圆环,实现图片镂空
  9. 网卡属于计算机网络的传输介质吗,两台电脑通过双绞线和网卡互连算不算计算机网络?...
  10. nodegitgithub