angular-websocket學習筆記

主要記錄在開發中使用angular-websocket的學習心得,可以直接跳過「前言」,如有錯誤請批評指正。

前言

最近一直在學習開發一款物聯網項目。通過後端管理平臺,可以將設備的信息反饋到用戶端,並實時控制。後端用的workerman+websocket技術,可以實現長連接,雙向通信。

主要是通信協議和指令的設計。設備端和用戶端先在PC端模擬,demo通過JavaFX基本實現。因爲考慮可以通過多種終端控制設備,初步想法是設計一款移動版web的前端。

web端的開發自己還是小白一枚。調研到angular+jqweui還挺符合自己的簡單需求,可以實現單頁web應用、仿微信UI。

由於JavaScript中提供websocket API,我們不需要操心數據的封裝和發送。只需要關心自己的業務邏輯(設計指令實現功能),和與UI的交互。業務邏輯的設計不再囉嗦。

由於剛開始學習angulajs,發現將基於websocket的業務邏輯(主要就是①接收反饋後解析,②封裝不同的指令發送)寫在js文件後,可以實現②,但沒有辦法實現異步UI的刷新。

異步的websocket消息過來怎麼更新UI?

我們知道angularjs的優點就是可以實現UI(html)和業務(js)的分離,類似與軟件UI開發中MVC的思想。但是軟件UI中通常是通過多線程異步更新UI的,並且API都封裝好了。

AngularJS 教程 | 菜鳥教程中可以通過$http讀取遠程服務器的數據並異步更新UI,是對http數據的支持。但是websocket呢?

angular-websocket

通過調用angular-websocket,可以將websocket業務邏輯直接寫在factory模塊中。

  • factory服務的原理,其實就是注入服務,用來返回對象給$scope的,參考:深究AngularJS——自定義服務詳解(factory、service、provider)

  • 其中,angular-websocket的回調函數onMessage最爲重要了,就是用來接收websocket消息,並且可以實現UI的異步刷新。文檔的說明在此:

    Register a callback to be fired on every message received from the websocket, or optionally just when the message’s data property matches the filter provided in the options object. Each message handled will safely call rootScope. digest() unless autoApply is set to `false in the options. Callback gets called with a MessageEvent object.

  • 綜上,注入factory服務,其中最重要的是實現onMessage,根據不同的業務邏輯功能,其流程:接收到反饋消息——>定義成一個對象——>在factory中return對象——>對象要與UI中$scope變量對應——>異步刷新UI的scope。

  • 注意:factory返回的對象組,①只能是數組和方法。②並且都需要在scope中聲明,要不然咋刷新呢。由於官方的demo很簡單,演示下自己的demo:

app.factory('Messages', Messages);
app.controller('mainController', function($scope, $rootScope, Messages) {
    //連接websocket
    $rootScope.Messages = Messages;
});
//反饋數據,需要異步刷新到UI中
var dataA, dataB = null;
var dataB = [];

function Messages($websocket) {

    ws = $websocket("ws://"+document.domain+":8282");


    ws.onMessage(onmessage);

    ws.onError(function(event) {
      console.log("連接異常");
    });

    ws.onClose(function(event) {
        console.log("連接關閉");
    });

    ws.onOpen(function() {
      console.log("連接中..");
    });
    // setTimeout(function() {
    //   ws.close();
    // }, 500)

    return {
        getdataA: function() {
            return dataA;
        },
        getdataB: function() {
           return dataB;
        },
        dataC: dataC
}

// 服務端發來消息時
function onmessage(e)
{
    console.log('接受到的數據:' + e.data);
    var data = JSON.parse(e.data);
    switch(data['type']){
        // 服務端ping客戶端
        case xxx:
            parsedataA(data);
        break;
        case 'xxx':
            parsedataB(data);
        break; 
        case 'xxx':
            parsedataC(data);
        break;
    }
}

    //解析反饋A
    function parsedataA(data){
        dataA = xxx;
    }

    //解析反饋B
    function parsedataA(data){
        dataB = xxx;
    }

    //解析反饋c
    function parsedataA(data){
        datac = [xxx];
    }

    //發送指令A
    function sendA(pid){
        console.log('發送消息A');
        send(xxx, xxx);
    }
    //發送指令B
    function sendB(){
        console.log('發送消息C');
        send(xxx, xxx);
    }
    ...

    //發送指令消息
    function send(type, content){
        var json_data = '{"type":"'+ type +'","content":'+ content +'}';
        ws.send(json_data);
        console.log("發送的數據: "+ json_data + "\n");
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章