flask实现websocket有两种方式:flask_sockets,Flask-SocketIO。
flask_sockets:该方式是flask对websocket的最原始封装,功能较为单一;
Flask-SocketIO:该方式所能提供功能较多,不但实现了socket的基本通信功能,也可以结合flask相关接口,使其更加完备。
安装flask-sockets包,版本0.2.1
pip install flask-sockets
路由包括两部分,其一为页面路由,其二为后台数据交换路由。
def handle_route_websocket_simple(app): @app.route(‘/ws/test_1‘) def page_ws_test_1(): return render_template(‘websocket_test.html‘, title="websocket test")# websocketdef handle_route_websocket(app_socket): @app_socket.route(‘/ws/test_2‘) def page_websocket_test(ws): now = time.strftime(‘%Y-%m-%d-%H-%M-%S‘, time.localtime(time.time())) while not ws.closed: # 回传给clicent message = ws.receive() # 接收到消息 if message is not None: print("client says(%s): %s" %(now, message)) ws.send(str("回执:server已收到消息!-- %s " % now)) ws.send(str(json.dumps(message))) # 回传给clicent else: print(now, "no receive")
添加路由是用方法完成的,后面两句是看一下路由映射关系。
# websocket页面
from flask_sockets import Sockets
app_socket = Sockets(app)from .routes import handle_route_websocket, handle_route_websocket_simplehandle_route_websocket_simple(app)handle_route_websocket(app_socket)print(app_socket.url_map)print(app.url_map)
路由映射关系:
Map([<Rule '/ws/test_2' -> <function handle_route_websocket.<locals>.page_websocket_test at 0x0000009D88A83620>>])Map([<Rule '/ws/test_1' (GET, OPTIONS, HEAD) -> page_ws_test_1>,<Rule '/hello' (GET, OPTIONS, HEAD) ->hello>,<Rule '/static/<filename>' (GET, OPTIONS, HEAD) -> static>])
2.2.2 启动服务器
因为返回来的报文有websocket和HTTP两种,需要在WSGI中进行区分。
具体可以看下WebSocketHandler,此处略。def run_app_websocket(): app_websocket = WSGIServer((‘0.0.0.0‘, 9000), flask_app, handler_class=WebSocketHandler) app_websocket.serve_forever()if __name__ == ‘__main__‘: pass #run_app() run_app_websocket()2.3 前端
<html> <head> <meta charset="utf-8" /> <title>websocket 测试</title> <script src="https://cdn.bootcss.com/jquery/3.2.0/jquery.js"></script> <script type="text/javascript"> function WebSocketTest() { if ("WebSocket" in window) { // alert("您的浏览器支持 WebSocket!"); // 打开一个 web socket var ws = new WebSocket("ws://localhost:9000/ws/test_2"); ws.onopen = function(){ // Web Socket 已连接上,使用 send() 方法发送数据 ws.send("请发送数据"); $("#r_s").append("数据发送中...<br>") }; ws.onmessage = function (evt){ var received_msg = evt.data; $("#r_s").append("server says: "+decodeURI(received_msg)+"<br>") //ws.send("数据已收到。") }; ws.onclose = function(){ // 关闭 websocket ws.send("正在关闭连接...") $("#r_s").append("连接已关闭...<br>") }; } else { // 浏览器不支持 WebSocket alert("您的浏览器不支持 WebSocket!"); } } </script> </head> <body> <div id="sse"> <a href="javascript:WebSocketTest()">运行 WebSocket</a> </div> <div id="r_s"> 操作记录: <br /> </div> </body></html>
3.测试结果
后端:
client says(2019-09-27-19-54-33): 请发送数据页面:
操作记录: 数据发送中...server says: 回执:server已收到消息!-- 2019-09-27-19-54-33 server says: 第0条消息。。。server says: 第1条消息。。。server says: 第2条消息。。。server says: 第3条消息。。。server says: 第4条消息。。。server says: 第5条消息。。。server says: 第6条消息。。。server says: 第7条消息。。。server says: 第8条消息。。。server says: 第9条消息。。。连接已关闭...