使用 flask-socketIO 完成定时推送

Posted by Yun on Tue, Jun 4, 2019

flask 是一款 python 的 web 框架,而 socketIO 则是一款用于实时通信的高级封装库,它可以智能选择 websocket、长轮询等方式进行双工通信。

1. 面向事件驱动的 socketIO

socketIO 原本是一款 node.js 库,也有众多其他语言的实现版本。socketIO 的思想是使用事件驱动,通过不同的事件收发来完成通信。而 flask-socketIO 同样也是面向事件驱动的。

2. flask 使用 flask-socketIO 完成定时推送

定时推送,是我们使用 websocket 的主要目的之一,flask 完成定时推送,主要使用后台的线程来完成。

在 flask-socketIO 的 github 示例代码中,就有这样的逻辑。

下面是本文提供的一种实现方式:

 1from threading import Lock
 2from flask import Flask
 3from flask_socketio import SocketIO
 4import time
 5import json
 6import random
 7
 8ASYNC_MODE = None
 9NS_DATA_PUSH = '/ws/dataPush'
10RANDOM_MIN = 0
11RANDOM_MAX = 50
12
13app = Flask(__name__)
14app.config['SECRET_KEY'] = 'secret!'
15socketio = SocketIO(app, async_mode=ASYNC_MODE)
16
17thread = None
18thread_lock = Lock()
19connections = 0
20
21
22def background_data_push():
23    global connections
24    while connections > 0:
25        with open('./data/pushData.json', 'r', encoding='utf-8') as f:
26            obj = json.load(f)
27
28        app.logger.info("DateTime: " + str(time.asctime()))
29        socketio.emit('push_data', obj, namespace=NS_DATA_PUSH)
30        socketio.sleep(1)
31
32
33@socketio.on('connect', namespace=NS_DATA_PUSH)
34def handle_connect():
35    global thread, thread_lock, connections
36    with thread_lock:
37        connections += 1
38        app.logger.info('Connection +1')
39        if (thread is None) or (not thread.is_alive()):
40            thread = socketio.start_background_task(background_data_push)
41
42
43@socketio.on('disconnect', namespace=NS_DATA_PUSH)
44def handle_disconnect():
45    global thread, thread_lock, connections
46    with thread_lock:
47        connections -= 1
48        app.logger.info('Connection -1')
49        if connections == 0:
50            thread.join()
51
52
53if __name__ == '__main__':
54    socketio.run(app, debug=True)

3. 相关链接


版权声明:本文遵循 CC BY-SA 4.0 版权协议,转载请附上原文出处链接和本声明。

Copyright statement: This article follows the CC BY-SA 4.0 copyright agreement. For reprinting, please attach the original source link and this statement.