WebSocket是啥?
WebSocket是HTML5引入的新的通信协议,主要由Web客户端和服务器实现,当然它也可以在Web之外实现。
与HTTP连接不同,WebSocket连接是客户端和服务器之间永久的双向通信通道,其中任何一个都可以启动交换。 一旦建立,连接一直有效,直到其中一方断开连接。
flask实现websocket的两种方式
flask 实现websocket有两种方式实现,一种是flask_sockets方式,该方式是flask对websocket的最原始封装,功能较为单一,第二种方式Flask-SocketIO对websocket的封装,该方式所能提供功能较多,不但实现了socket的基本通信功能,也可以结合flask相关接口,使其更加完备,因此网上对该api介绍也较多。
使用Flask-Sockets
服务端
服务端receive()方法,必须接收客户端发送的数据,才能实现两两互相通信。
#!/usr/bin/env python
# encoding: utf-8
"""
@version: v1.0
@author: W_H_J
@license: Apache Licence
@contact: 415900617@qq.com
@software: PyCharm
@file: flaskWebSocket.py
@time: 2019/2/19 10:20
@describe: flask_sockets 实现websocket
"""
import json
import sys
import os
from flask_sockets import Sockets
import time
from gevent import monkey
from flask import Flask
from gevent import pywsgi
from geventwebsocket.handler import WebSocketHandler
sys.path.append(os.path.abspath(os.path.dirname(__file__) + '/' + '..'))
sys.path.append("..")
monkey.patch_all()
app = Flask(__name__)
sockets = Sockets(app)
now = time.strftime('%Y-%m-%d-%H-%M-%S', time.localtime(time.time()))
@sockets.route('/test') # 指定路由
def echo_socket(ws):
while not ws.closed:
ws.send(str("message test!")) # 回传给clicent
""" 服务端必须接收到客户端发的消息才能保持该服务运行,如果ws.receive()没有接收到客户端发送的
消息,那么它会关闭与客户端建立的链接
底层解释:Read and return a message from the stream. If `None` is returned, then
the socket is considered closed/errored.
所以客户端只建立连接,不与服务端交互通信,则无法实现自由通信状态,之后在客户端代码处会有详细内容。
"""
message = ws.receive() # 接收到消息
if message is not None:
print("%s receive msg==> " % now, str(json.dumps(message)))
""" 如果客户端未发送消息给服务端,就调用接收消息方法,则会导致receive()接收消息为空,关闭此次连接 """
ws.send(str(json.dumps(message))) # 回传给clicent
else:
print(now, "no receive")
@app.route('/')
def hello():
return 'Hello World! server start!'
if __name__ == "__main__":
server = pywsgi.WSGIServer(('0.0.0.0', 5000), app, handler_class=WebSocketHandler)
print('server start')
server.serve_forever()
HTML客户端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.2.0/jquery.js"></script>
</head>
<body>
<div id="time" style="width: 300px;height: 50px;background-color: #0C0C0C;
color: white;text-align: center;line-height: 50px;margin-left: 40%;font-size: 20px"></div>
<script>
var ws = new WebSocket("ws://127.0.0.1:5000/test"); #连接server--test
ws.onmessage = function (event) {
content = document.createTextNode(event.data); # 接收数据
$("#time").html(content);
};
</script>
</body>
</html>
python客户端
#!/usr/bin/env python
# encoding: utf-8
"""
@version: v1.0
@author: W_H_J
@license: Apache Licence
@contact: 415900617@qq.com
@software: PyCharm
@file: flaskclicent.py
@time: 2019/2/19 10:34
@describe: flask_sockets 客户端
"""
import sys
import os
import datetime
sys.path.append(os.path.abspath(os.path.dirname(__file__) + '/' + '..'))
sys.path.append("..")
from websocket import create_connection
# websocket-client
# 通过socket路由访问
now = datetime.datetime.now()
print(now)
def send_query_webSocket():
ws = create_connection("ws://10.10.20.21:9000/test")
result_1 = ws.recv() # 接收服务端发送的连接成功消息
print(result_1)
"""
上面recv()方法接收服务端 发送的第一条消息:ws.send(str("message test!")) # 回传给clicent
下面再要接收消息,必须先给服务端发送一条消息,不然服务端message = ws.receive() 的receive方法
没有收到消息,而这里直接调用rece()方法去接收服务端消息,则会导致服务端关闭此次连接;
底层方法介绍:Read and return a message from the stream. If `None` is returned, then
the socket is considered closed/errored.
虽然此次连接关闭了,但是对于客户端来说并不知情,而客户端recv()方法又是一个阻塞方式运行,所以会导致
客户端永远阻塞在这里无法关闭,这也是flask_sockets 客户端服务端交互的一个缺点吧。
"""
ws.send("I am test msg!")
result = ws.recv()
print(result)
ws.close()
return True
if __name__ == '__main__':
send_query_webSocket()