nodejs 搭建websocket長連接服務 實現前端頁面調用第三方接口獲取數據的實時更新


1、頁面 與 js :

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>WebSocket Echo Demo</title>
    <meta name="viewport" content="width=device-width, initial-scale=1"/>
    <link href="../bootstrap-3.3.5/css/bootstrap.min.css" rel="stylesheet" />
    <script src="../js/jquery-1.12.3.min.js"></script>
    <script src="../bootstrap-3.3.5/js/bootstrap.min.js"></script>
</head>

<body>
    <div class="vertical-center" id="test">
        <div class="container">
            <h1>Stock Chart over WebSocket</h1>
            <div>{{message}}</div>
            <!--<button class="btn btn-primary">開始</button>
            <button class="btn btn-danger">停止</button>-->
            <table class="table" id="stockTable">
                <thead>
                    <tr>
                        <th>Symbol</th>
                        <th>Price</th>
                    </tr>
                </thead>
                <tbody id="stockRows">

                    <tr>
                        <td>
                            <h3>售票數</h3>
                        </td>
                        <td id="sale">
                            <h3><span class="label label-default" id="num1">{{numData}}</span></h3>
                        </td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
    <script>
        var ws = new WebSocket("ws://localhost:8181");
        var stock_request = { "stocks": ["AAPL", "MSFT", "AMZN", "GOOG", "YHOO"] };
        var isClose = false;
        var stocks = {
            "AAPL": 0, "MSFT": 0, "AMZN": 0, "GOOG": 0, "YHOO": 0
        };
        function updataUI() {
            // debugger
            ws.onopen = function (e) {
                console.log('Connection to server opened');
                isClose = false;
                //ws.send(JSON.stringify(stock_request));
                //ws.send('plese to conection');
                //console.log("sened a mesg");
            }
            // UI update function
            var changeStockEntry = function (symbol, originalValue, newValue) {
                var valElem = $('#' + symbol + ' span');
                valElem.html(newValue.toFixed(2));
                if (newValue < originalValue) {
                    valElem.addClass('label-danger');
                    valElem.removeClass('label-success');
                } else if (newValue > originalValue) {
                    valElem.addClass('label-success');
                    valElem.removeClass('label-danger');
                }
            }
            // WebSocket message handler
            ws.onmessage = function (e) {
                var stocksData = JSON.parse(e.data);
                console.log(stocksData);
                for (var symbol in stocksData) {
                    if (stocksData.hasOwnProperty(symbol)) {
                        changeStockEntry(symbol, stocks[symbol], stocksData[symbol]);
                        stocks[symbol] = stocksData[symbol];
                    }
                }
            };
        }

        //updataUI();

        $(".btn-primary").click(function () {
            if (isClose) {
                ws = new WebSocket("ws://localhost:8181");
            }
            updataUI();
        });
        $(".btn-danger").click(function () {
            ws.close();
        });

        ws.onclose = function (e) {
            console.log("Connection closed", e);
            isClose = true;
        };




    </script>

    <script src="config/jquery-1.10.2.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script type="text/javascript">
        var app2 = new Vue({
            el: '#test',
            data: {
                message: '頁面加載於 ' + new Date().toLocaleString(),
                numData: 0,

            },
            mounted: function () {
            },
            methods: {

                init() {
                    //debugger
                    that = this;
                    var ws = new WebSocket('ws://localhost:8181');
                    ws.onopen = function (e) {
                        console.log('開始連接服務器')
                        // 發送消息

                        ws.send('連接到服務器');

                    }
                    ws.onmessage = function (event) { // 監聽消息
                        //debugger
                        //定時器設置數字變化的滾動效果
                        var number = event.data - that.numData;
                        var boo = number > 0 ? true : false;// boo = true動畫效果為遞增;boo = false動畫效果為遞減
                        setInterval(function () {
                            if (boo) {
                                //數字變大
                                number--;
                                if (number >= 0) {
                                    that.numData++;
                                    return that.numData;
                                }
                            }else {
                                //數字變小
                                number++;
                                if (number <= 0) {
                                    that.numData--;
                                    return that.numData;
                                }
                            }
                        }, 1);
                        

                        //that.numData = event.data;直接賦值沒有動畫效果,想要動畫效果采用上面方法
                        console.log("監聽到消息:" + that.numData);

                        //that.numData = msg.data.salesNum;
                    }
                    ws.onerror = function (evt) {
                        //產生異常
                        console.log("產生異常");
                    };
                    ws.onclose = function (evt) {
                        //產生異常
                        console.log("關閉");
                    };
                },
            },
            created: function () {
                this.init();
            }
        });
    </script>
</body>
</html>

 

 

nodejs 搭建server.js服務 :

var WebSocketServer = require('ws').Server,
wss = new WebSocketServer({ port: 8181 });

//引入模塊
var http = require('http');
const querystring = require('querystring');
var numData = -1;
var isTrue = false;
var clientStockUpdater;

//定義請求消息頭
var headers = {
    'XverifyApi': 'fzY08dHMxkRRaDM9m7y+ptFf9qsVzmLb0enT7NRfBdAhtI0+iKv3Sg==',
    'XownerId': 'fqszs',
    'XsysId': 'sys-0'
};
//定義請求消息url和頭部
var options = {
    method: 'GET',
    url: 'http//api.whlyw.net/bo/api/v1/big-data-ticket-market/list/res/sales',
    headers: headers
};

function handleGetData() {
    //發送請求
    var request = require('request');
    
    //console.log("33");

    request({
        url: 'http://api.whlyw.net/bo/api/v1/big-data-ticket-market/list/res/sales',
        method: 'GET',
        headers: headers
    }, function (error, response, body) {
       // console.log(response.statusCode)
        if (!error && response.statusCode == 200) {
           // console.log(JSON.parse(body)) // 請求成功的處理邏輯,注意body是json字符串  .data.salesNum
            console.log('頁面數' + numData);
            console.log('售票數'+JSON.parse(body).data.salesNum);
            if (numData == JSON.parse(body).data.salesNum) {
                console.log('進入到頁面數與售票數一致的方法中');
                isTrue = false;
            } else {
                console.log('進入到頁面數與售票數不一致的方法中');
                numData = JSON.parse(body).data.salesNum
                isTrue = true;
            }  
            //console.log(numData);
            //return numData;
        }
    })

    //request(options, function (error, response, body) {
    //    console.log("33"+response.statusCode);
    //    if (!error && response.statusCode == 200) {
    //        console.log(body) // 請求成功的處理邏輯,注意body是json字符串
    //    }
    //});


    //var req = http.request(options, function (res) {
    //    console.log(res.statusCode);
    //    console.log(res.headers);
    //    res.setEncoding('utf-8');
    //    res.on('data', function (chunk) {
    //        //輸出響應內容
    //        console.log("GGG"+chunk);

    //        ////將chunk轉為對象
    //        //console.log(JSON.parse(chunk));
    //        ////通過對象調用各參數,不發散其他操作
    //        //console.log(JSON.parse(chunk).resultcode);
    //    });
    //    //res.on('end', function () {
    //    //    console.log('響應結束********');
    //    //});
    //});
    ////監控錯誤情況時報錯
    //req.on('error', function (e) {
    //    console.error(e);
    //});
    ////結束請求輸入
    //req.end();
}



wss.on('connection', function (ws) {
    var sendStockUpdates = function (ws) {
        //console.log("11", ws.readyState);
        if (ws.readyState == 1) {
            var stocksObj = {};
           // console.log("第一次");
            handleGetData();

            console.log("dd" + isTrue);
            if (isTrue) {
                console.log("發送前");
                ws.send(JSON.stringify(numData));
            }
        }
    }
    
    ws.on('message', function (message) {
        //var stockRequest = JSON.parse(message);
        var stockRequest = message;
        console.log("收到消息", stockRequest);
        //clientStocks = stockRequest['stocks'];
        //sendStockUpdates(ws);

        //setInterval第一次執行時會延遲對應時間,所以這里先執行該方法;如果每秒輪詢就不用下面操作,下面的請求接口還有回調需要時間來的延遲
        //if (ws.readyState == 1) {
        //    var stocksObj = {};
        //    handleGetData();
        //    console.log("dd" + isTrue);
        //    if (!isTrue) {
        //        console.log("發送前");
        //        ws.send(JSON.stringify(numData));
        //    }
        //}

        clientStockUpdater = setInterval(function () {
           // console.log("第二次");
            sendStockUpdates(ws);
        }, 1000);
    });
    ws.on('close', function () {
        if (typeof clientStockUpdater !== 'undefined') {
            clearInterval(clientStockUpdater);
        }
    });
});

備注:

1、cmd打開命令窗口,進入到nodejs安裝目錄下,執行全局安裝request模塊命令:

npm i request -g

2、進入到項目所在目錄執行啟動node服務命令:node server.js。  

3、再瀏覽器打開頁面 初始化並創建websocket長連接,實時監聽數據變化。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM