python基於flask_sockets實現WebSocket——叄

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: [email protected]
@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: [email protected]
@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()

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章