• Node.js--WebSocket使用示例


    一、基本使用
    1.安装node
     
    2.安装ws模块
    ws:是nodejs的一个WebSocket库,可以用来创建服务。 https://github.com/websockets/ws
    npm install ws
     
    3.创建服务端
    在项目里面新建一个server.js,创建服务,指定8181端口,将收到的消息log出来。
    var WebSocketServer = require('ws').Server,
    wss = new WebSocketServer({ port: 8181 });
    wss.on('connection', function (ws) {
        console.log('client connected');
        ws.on('message', function (message) {
            console.log(message);
        });
    });
     
    4.创建客户端
    在页面上建立一个WebSocket的连接。用send方法发送消息。
     var ws = new WebSocket("ws://localhost:8181");
        ws.onopen = function (e) {
            console.log('Connection to server opened');
        }
        function sendMessage() {
            ws.send($('#message').val());
        }
    运行之后如下,服务端即时获得客户端的消息。
    上面的例子很简单,只是为了演示如何运用nodejs的ws创建一个WebSocket服务器。且可以接受客户端的消息。
     
    二、示例--股票刷新
    下面这个例子演示股票的实时更新。客服端只需要连接一次,服务器端会不断地发送新数据,客户端收数据后更新UI.页面如下,有五只股票,开始和停止按钮测试连接和关闭。
     服务端:
     1.模拟五只股票的涨跌。
    var stocks = {
        "AAPL": 95.0,
        "MSFT": 50.0,
        "AMZN": 300.0,
        "GOOG": 550.0,
        "YHOO": 35.0
    }
    function randomInterval(min, max) {
        return Math.floor(Math.random() * (max - min + 1) + min);
    }
    var stockUpdater;
    var randomStockUpdater = function() {
        for (var symbol in stocks) {
            if(stocks.hasOwnProperty(symbol)) {
                var randomizedChange = randomInterval(-150, 150);
                var floatChange = randomizedChange / 100;
                stocks[symbol] += floatChange;
            }
        }
        var randomMSTime = randomInterval(500, 2500);
        stockUpdater = setTimeout(function() {
            randomStockUpdater();
        }, randomMSTime);
    }
    randomStockUpdater();
     
    2.连接建立之后就开始更新数据
    wss.on('connection', function (ws) {
        var sendStockUpdates = function (ws) {
            if (ws.readyState == 1) {
                var stocksObj = {};
                for (var i = 0; i < clientStocks.length; i++) {
                  var symbol = clientStocks[i];
                    stocksObj[symbol] = stocks[symbol];
                }
                if (stocksObj.length !== 0) {
                    ws.send(JSON.stringify(stocksObj));//需要将对象转成字符串。WebSocket只支持文本和二进制数据
                    console.log("更新", JSON.stringify(stocksObj));
                }
               
            }
        }
        var clientStockUpdater = setInterval(function () {
            sendStockUpdates(ws);
        }, 1000);
        ws.on('message', function (message) {
            var stockRequest = JSON.parse(message);//根据请求过来的数据来更新。
            console.log("收到消息", stockRequest);
            clientStocks = stockRequest['stocks'];
            sendStockUpdates(ws);
        });
     
    客户端:
    //建立连接
    var ws = new WebSocket("ws://localhost:8181");
    //onopen直接只有在连接成功后才会触发,在这个时候将客户端需要请求的股票发送给服务端。
    var isClose = false;
        var stocks = {
            "AAPL": 0, "MSFT": 0, "AMZN": 0, "GOOG": 0, "YHOO": 0
        };
        function updataUI() {
            ws.onopen = function (e) {
                console.log('Connection to server opened');
                isClose = false;
                ws.send(JSON.stringify(stock_request));
                console.log("sened a mesg");
            }
            //更新UI
            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');
                }
            }
            // 处理受到的消息
            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();
    运行效果如下:
    只需要请求一次,数据就会不断的更新,效果是不是很赞.
    (美股的涨跌和A股的颜色是反的,即红跌绿涨)
     
    二、示例--聊天室
    上面的例子是连接建立之后,服务端不断给客户端发送数据。接下来例子是一个简单的聊天室类的例子。可以建立多个连接。
    1.安装node-uuid模块,用来给每个连接一个唯一号。
    npm install node-uuid
     
    2.服务端消息发送
    消息类型分notification和message两种,前者是提示信息,后者是聊天内容。消息还包含一个id、昵称和消息内容。
    我们好知道readyState有四个值,OPEN表示连接建立可以发送消息。如果页面关闭了,为WebSocket.CLOSE。
    function wsSend(type, client_uuid, nickname, message) {
        for (var i = 0; i < clients.length; i++) {
            var clientSocket = clients[i].ws;
            if (clientSocket.readyState === WebSocket.OPEN) {
                clientSocket.send(JSON.stringify({
                    "type": type,
                    "id": client_uuid,
                    "nickname": nickname,
                    "message": message
                }));
            }
        }
    }
     
    3.服务端处理连接
    每新增加一个连接,都会发送一条匿名用户的加入的提示消息,如果消息中带有“/nick” 认为这一个修改昵称的消息。然后更新客户端的昵称。其他都会当做聊天消息处理。
    wss.on('connection', function(ws) {
        var client_uuid = uuid.v4();
        var nickname = "AnonymousUser" + clientIndex;
        clientIndex += 1;
        clients.push({ "id": client_uuid, "ws": ws, "nickname": nickname });
        console.log('client [%s] connected', client_uuid);
        var connect_message = nickname + " has connected";
        wsSend("notification", client_uuid, nickname, connect_message);
        console.log('client [%s] connected', client_uuid);
        ws.on('message', function(message) {
            if (message.indexOf('/nick') === 0) {
                var nickname_array = message.split(' ');
                if (nickname_array.length >= 2) {
                    var old_nickname = nickname;
                    nickname = nickname_array[1];
                    var nickname_message = "Client " + old_nickname + " changed to " + nickname;
                    wsSend("nick_update", client_uuid, nickname, nickname_message);
                }
            } else {
                wsSend("message", client_uuid, nickname, message);
            }
        });
    处理连接关闭:
      var closeSocket = function(customMessage) {
            for (var i = 0; i < clients.length; i++) {
                if (clients[i].id == client_uuid) {
                    var disconnect_message;
                    if (customMessage) {
                        disconnect_message = customMessage;
                    } else {
                        disconnect_message = nickname + " has disconnected";
                    }
                    wsSend("notification", client_uuid, nickname, disconnect_message);
                    clients.splice(i, 1);
                }
            }
        };
        ws.on('close', function () {
            closeSocket();
        });
     
    4.客户端
    js:
      //建立连接
            var ws = new WebSocket("ws://localhost:8181");
            var nickname = "";
            ws.onopen = function (e) {
                console.log('Connection to server opened');
            }
            //显示
            function appendLog(type, nickname, message) {
                if (typeof message == "undefined") return;
                var messages = document.getElementById('messages');
                var messageElem = document.createElement("li");
                var preface_label;
                if (type === 'notification') {
                    preface_label = "<span class="label label-info">*</span>";
                } else if (type == 'nick_update') {
                    preface_label = "<span class="label label-warning">*</span>";
                } else {
                    preface_label = "<span class="label label-success">"
                    + nickname + "</span>";
                }
                var message_text = "<h2>" + preface_label + "&nbsp;&nbsp;"
                + message + "</h2>";
                messageElem.innerHTML = message_text;
                messages.appendChild(messageElem);
            }
            //收到消息处理
            ws.onmessage = function (e) {
                var data = JSON.parse(e.data);
                nickname = data.nickname;
                appendLog(data.type, data.nickname, data.message);
                console.log("ID: [%s] = %s", data.id, data.message);
            }
            ws.onclose = function (e) {
                appendLog("Connection closed");
                console.log("Connection closed");
            }
            //发送消息
            function sendMessage() {
                var messageField = document.getElementById('message');
                if (ws.readyState === WebSocket.OPEN) {
                    ws.send(messageField.value);
                }
                messageField.value = '';
                messageField.focus();
            }
            //修改名称
            function changName() {
                var name = $("#name").val();
                if (ws.readyState === WebSocket.OPEN) {
                    ws.send("/nick " + name);
                }
            }
     运行结果:
     页面关闭之后,连接马上断开。
     
     

  • 相关阅读:
    五种开源协议(GPL,LGPL,BSD,MIT,Apache)
    我想要做的编码机器人
    2017年前端框架、类库、工具大比拼
    Python实现好友全头像的拼接
    Python 中的闭包与装饰器
    Vuex2.0边学边记+两个小例子
    Vue.js写一个SPA登录页面的过程
    react与vue
    20行js代码制作网页刮刮乐
    css3动画详解
  • 原文地址:https://www.cnblogs.com/absoluteli/p/14125083.html
Copyright © 2020-2023  润新知