websocket實時監控畫面

  Ajax輪詢是經過特定的的時間間隔(如每1秒),由瀏覽器對服務器發出HTTP請求,而後由服務器返回最新的數據給客戶端的瀏覽器。這種簡單粗暴模式有一個明顯的缺點,就是瀏覽器須要不斷的向服務器發出請求,HTTP請求可能包含較長的頭部,其中真正有效的數據可能只是很小的一部分,顯然這樣會浪費不少的帶寬等資源(對於不少局域網內的企業應用,這個簡單粗暴模式確實解決問題)。html

1.1.    websocket簡介

  本文接下來採用一種更加高效率的服務端主動推送技術(WebSocket )來提升數據的傳輸效率。WebSocket通訊協議 是 HTML5 開始支持的一種在單個 TCP 鏈接上進行全雙工通信的協議。在 WebSocket 技術架構中,瀏覽器和服務器只須要完成一次握手,二者之間就直接能夠建立持久性的鏈接,並進行雙向數據傳輸。python

  瀏覽器經過 JavaScript 向服務器發出創建 WebSocket 鏈接的請求,鏈接創建之後,客戶端和服務器端就能夠經過 TCP 鏈接直接交換數據。當你獲取 Web Socket 鏈接後,能夠經過 send() 方法來向服務器發送數據,並經過 onmessage 事件來接收服務器返回的數據。  git

1.2.  建立一個Flask-Sockets服務端項目

  本例咱們經過VS2019建立一個空的Python項目,來實現Flask-Sockets服務端代碼,咱們在現有的解決方案裏添加一個Project,以下圖:github

 

1.2.1. 安裝Flask-Sockets組件

Flask咱們可採用Flask-Sockets組件來實現websocket 通訊驗證原型,web

組件網址:https://github.com/heroku-python/flask-socketsflask

安裝命令:pip install Flask-Sockets瀏覽器

vs community 咱們能夠直接在Python Environment 安裝Flask-Sockets組件(注意字母大小寫,不然不能安裝成功),以下圖:服務器

1.2.2. 實現websocket服務端源碼

服務端先實現由服務端定時推送一個自增的變量值給客戶端,代碼以下:websocket

      
from flask import Flask
from flask_sockets import Sockets
import time

app = Flask(__name__)
sockets = Sockets(app)


@sockets.route('/tagCurValue')
def tagCurValue(ws):
    '''
        代碼模擬每5秒鐘,定時給客戶端推送一個自增的變量數據
    '''
    n=0
    while not ws.closed:
        n=n+1
        ws.send(str(n))
        print("tag curent value:"+ str(n))
        time.sleep(5)


@app.route('/')
def hello():
    return 'Hello World!'


if __name__ == "__main__":
    from gevent import pywsgi
    from geventwebsocket.handler import WebSocketHandler
    server = pywsgi.WSGIServer(('0.0.0.0', 5000), application=app, handler_class=WebSocketHandler)
    print('Server Start')
    server.serve_forever()  

server = pywsgi.WSGIServer(('0.0.0.0', 5000), application=app, handler_class=WebSocketHandler)網絡

上述代碼的'0.0.0.0'要注意賦值,組件的Example例子是一個空字符串,筆者也踩了坑,花費很多時間才找到案例運行失敗的緣由。

1.2.3. 運行FlaskSocketSvr服務端

首先,咱們須要把FlaskSocketSvr設置成解決方案的默認項目,後然F5運行測試環境以下圖:

瀏覽器地址欄輸入如下網址:http://127.0.0.1:5000/ 結果以下圖:

 

1.2.4. 重構客戶端代碼

  如今咱們重構客戶端代碼以即可以訪問服務端提升的websocket URL得到數據更新

http://127.0.0.1:5000/tagCurValue 

UI JS代碼以下:

        //JQuery 代碼入口
        $(document).ready(function(){
 
            //setInterval("getData()",3000);

            if ("WebSocket" in window) {
                //鏈接server--TagCurValue
                var ws = new WebSocket("ws://127.0.0.1:5000/tagCurValue");
                //var ws = new WebSocket("ws://127.0.0.1:8008/tagCurValue");
                ws.onmessage = function (evt) {
                    // 接收數據
                    receivedMsg = evt.data;
                    $("#divTag").html(receivedMsg);

                };
            }

 
        });

  

如今咱們在Project經過Python菜單執行Start server,而後再F5運行服務端,咱們就能夠經過瀏覽器運行測試頁面了。

 

測試頁面url:http://127.0.0.1:8008/

 

咱們也能經過瀏覽器的開發工具查看網絡訪問只發生了一次。

 

1.3.    讀取opc服務的tag位號值

  最後,咱們再把tagCurValue'重構成真正讀取opc服務某一個tag位號的值。以完成了從UI端到服務端主動獲取opc服務tag位號值,並更新UI界面的技術原型。views文件函數tagCurValue'代碼修改以下:

@sockets.route('/tagCurValue')
def tagCurValue(ws):
    import OpenOPC
    while not ws.closed:
        opc = OpenOPC.client()
        opc.connect('Matrikon.OPC.Simulation')
        result= opc['Random.Int1']
        opc.close()
        ws.send(unicode( result))
        print("tag curent value:"+ unicode( result))
        time.sleep(5)

 如今,咱們從新運行測試環境,結果以下圖:

1.4.    小結

  本小節介紹瞭如何經過採用websocket技術,實現由服務端主動Send數據到UI端的通訊模式,客戶端實時刷新UI端tag位號的當前值,提升了數據傳輸的效率和性能,樣例的FlaskSocketSvr服務也演示了一個獨立的服務端到UI端的數據傳輸方式(獨立的服務端地址)。最後,新的服務也經過讀取OPC server的tag位號值演示了經過OPC Sever獲取監控設備數據的方式。

相關文章
相關標籤/搜索