前言
前段时间在做自有性能测试平台时,需要加入一个前端实时获取后端数据的功能。整个的项目前后端是分开的,后端项目用python的Flask框架实现,前端项目用Vue框架实现。因为我做后端,所以最开始想到的对我来说最简单的方法就是提供一个读取数据的接口,前端通过Ajax轮询的方式实时获取数据。但是轮询对前端来讲似乎工作量和复杂度高,而且考虑到网络资源的消耗,轮询显然不是一个最优的解决办法,于是想到通过websocket来解决。
知识点
websocket
对websocket的第一理解就是用于前后端实时通信,再深入研究发现其实它是一种协议。
WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。
HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
----摘自菜鸟教程
flask-socketio
后端选用了flask-socketio库来实现websocket功能。
初始化
from flask import Flask, render_template
from flask_socketio import SocketIO
app = Flask(__name__)
app.config.from_object("config.{}".format(os.getenv('FLASK_CONFIG') or "dev"))
socketio = SocketIO(app, cors_allowed_origins='*', async_mode='eventlet', engineio_logger=True)
if __name__ == '__main__':
socketio.run(app)
接收消息
使用flask-SocketIO,服务端需要为这些事件注册处理程序,这与视图函数如何处理路由类似。
命名事件
以下示例为未命名事件创建服务器端事件处理程序:
@socketio.on('message')
def handle_message(message):
print('received message: ' + message)
上面的示例使用字符串消息。另一种类型的未命名事件使用JSON数据:
@socketio.on('json')
def handle_json(json):
print('received json: ' + str(json))
最灵活的事件类型使用自定义事件名称。这些事件的消息数据可以是字符串,字节,int或JSON:
@socketio.on('my event')
def handle_my_custom_event(json):
print('received json: ' + str