赞
踩
WebSocket 是一种计算机通信协议,通过单个 TCP 连接提供全双工通信信道。WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API 中,客户端和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
在 Flask 中使用 flask-sockets
实现 WebSocket 通信。
Flask-Sockets 官方地址 https://github.com/heroku-python/flask-sockets
Flask 通过 flask-sockets
实现一个回声服务器作为示例(客户端发送什么数据,服务端就原样返回什么数据,就像回声一样)。
服务端示例:
pip3 install flask
pip3 install flask-sockets
flask_socket_demo.py 为服务端代码:
from flask import Flask from flask_sockets import Sockets app = Flask(__name__) sockets = Sockets(app) @sockets.route('/echo') def echo_socket(ws): while not ws.closed: message = ws.receive() ws.send(message) @app.route('/') def hello(): return 'Hello World!' if __name__ == "__main__": from gevent import pywsgi from geventwebsocket.handler import WebSocketHandler server = pywsgi.WSGIServer(('127.0.0.1', 5000), app, handler_class=WebSocketHandler) server.serve_forever()
python3 实现 websocket 客户端示例:
pip3 install websocket-client
websocket_client_demo.py 为客户端代码:
from websocket import create_connection def main(): url = 'ws://127.0.0.1:5000/echo' ws = create_connection(url) print("获取连接状态:", ws.connected) ws.send("Hello") response = ws.recv() print("获取服务器返回的结果: ", response) ws.close() if __name__ == '__main__': main()
from flask import Flask, Blueprint from flask_sockets import Sockets html = Blueprint(r'html', __name__) ws = Blueprint(r'ws', __name__) @html.route('/') def hello(): return 'Hello World!' @ws.route('/echo') def echo_socket(socket): while not socket.closed: message = socket.receive() socket.send(message) app = Flask(__name__) sockets = Sockets(app) app.register_blueprint(html, url_prefix=r'/') sockets.register_blueprint(ws, url_prefix=r'/') if __name__ == "__main__": from gevent import pywsgi from geventwebsocket.handler import WebSocketHandler server = pywsgi.WSGIServer(('127.0.0.1', 5000), app, handler_class=WebSocketHandler) server.serve_forever()
The websocket interface that is passed into your routes is provided by gevent-websocket. The basic methods are fairly straightforward — send, receive, send_frame, and close.
flask-sockets 是基于 gevent-websocket 实现的,使用的协程。如果接口中使用 time.sleep()
会阻塞进程,得用 gevent.sleep()
来进行切换使其他协程运行。
举个例子,有一个 http 轮询接口,浏览器每秒向服务端发送一次请求获取数据,那改造为 websocket 后,客户端与服务端建立连接后,客户端不再重复请求服务端了,服务端使用 gevent.sleep(1) 每隔一秒主动向客户端发送一次数据。
@sockets.route('/hello')
def echo_socket(ws):
message = socket.receive() # 接收客户端的数据
while not ws.closed:
ws.send('hello') # 向客户端发送数据
gevent.sleep(1) # 不能使用 time.sleep(1), 否则会阻塞协程的运行
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。