zoukankan      html  css  js  c++  java
  • Node构建WebSocket服务

    1,WebSocket和Http的区别?

    HTTP只能由客户端发起通信,不能主动获取实时数据。常用的方法轮询,就是用一个定时器,不停地发http请求(非常浪费资源)。

    我们希望的场景是这样的:服务端数据发生变化,主动向客户端推送最新信息,客户端也可以主动向服务器发送信息。这个时候

    服务器推送技术WebSocket就出场了。

    2,WebSocket 客户端提供的使用方法

    //1,WebSocket 实例化
    var ws = new WebSocket("ws://localhost:8181");
        ws.onopen = function (e) {
            console.log('客户端(client):与服务器的连接已打开')
      }
    2,readyState属性返回实例对象的当前状态
    
    //CONNECTING:值为0,表示正在连接。
    //OPEN:值为1,表示连接成功,可以通信了。
    //CLOSING:值为2,表示连接正在关闭。
    //CLOSED:值为3,表示连接已经关闭,或者打开连接失败。
    3,webSocket.onopen //指定连接成功后的回调函数
    4,webSocket.onclose //指定连接关闭后的回调函数
    5,webSocket.onmessage //收到服务器数据后的回调函数
    6,webSocket.send //方法用于向服务器发送数据
    7,webSocket.bufferedAmount //表示还有多少字节的二进制数据没有发送出去。它可以用来判断发送是否结束。
    8,webSocket.onerror //指定报错时的回调函数。
    
    ws.onopen = function () {
      ws.send('连接服务器成功');
    }
    
    //多个回调函数用
    ws.addEventListener('open', function (event) {
      ws.send('Hello Server!');
    });

    3,WebSocket 服务端实现

    不用全看,文档不是很全,技术是实现业务方法

    我简单写了几个demo

    3.1客户端向服务端发送消息

    安装node,和ws

    npm install ws

    新建文件

    客户端代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <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">
            <div class="container">
                <!-- 客户端加一个简单的input输入框和一个发送按钮 -->
                <form role="form" id="chat_form" onsubmit="sendMessage(); return false;" style="margin-top:100px;">
                    <div class="form-group">
                        <input class="form-control" type="text" name="message" id="message" value="" />
                    </div>
                    <button type="button" id="send" class="btn btn-primary" onclick="sendMessage();">
                        发送
                    </button>
                </form>
            </div>
        </div>
    </body>
    <script>
        //WebSocket实例化
        var ws = new WebSocket("ws://localhost:8181");
        ws.onopen = function (e) {
            //成功连接服务器回调
            console.log('客户端(client):与服务器的连接已打开')
        }
    
        function sendMessage() {
            ws.send($('#message').val());
        };
    </script>
    
    </html>

    服务端代码

    var WebSocketServer = require('ws').Server,
    wss = new WebSocketServer({ port: 8181 });//服务端口8181
    wss.on('connection', function (ws) {
        console.log('服务端:客户端已连接');
        ws.on('message', function (message) {
            //打印客户端监听的消息
            console.log(message);
        });
    });

    启动node服务

    3.2服务端图推送消息到客户端

    场景:车辆速度实时讲课监控。每三秒客户端更新一次信息

    同样客户端代码

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>服务器推送消息</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">
            <div class="container">
                <h1>检测车辆速度</h1>
                <button class="btn btn-primary">开始</button>
                <button class="btn btn-danger">停止</button>
                <table class="table" id="stockTable">
                    <thead>
                        <tr>
                            <th>车牌号</th>
                            <th>速度</th>
                        </tr>
                    </thead>
                    <tbody id="stockRows">
                        <tr>
                            <td>
                                <h3>A11111</h3>
                            </td>
                            <td id="A11111">
                                <h3><span class="label label-default label-success">00.00</span></h3>
                            </td>
                        </tr>
                        <tr>
                            <td>
                                <h3>A22222</h3>
                            </td>
                            <td id="A22222">
                                <h3><span class="label label-default label-success">00.00</span></h3>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>
        <script>
            var ws = new WebSocket("ws://localhost:8181");
            var stock_request = {
                "speed": ["A11111", "A22222"]
            };
            var isClose = false;
            var speed = {
                "A11111": 0,
                "A22222": 0,
            };
            //更新视图
            function updataSource() {
                ws.onopen = function (e) {
                    console.log('连接服务器成功');
                    isClose = false;
                    ws.send(JSON.stringify(stock_request));
                    console.log("发送消息成功");
                }
                // UI update function
                var changeSpeedEntry = function (item, newValue) {
                    var valElem = $('#' + item + ' span');
                    valElem.html(newValue.toFixed(2));
                }
                // 客户端WebSocket 监听消息并处理程序
                ws.onmessage = function (e) {
                    var speedData = JSON.parse(e.data);
                    console.log("收到数据:" + speedData);
                    for (var item in speedData) {
                        if (speedData.hasOwnProperty(item)) {
                            changeSpeedEntry(item, speedData[item]);
                            speed[item] = speedData[item];
                        }
                    }
                };
            }
    
            //业务代码
            updataSource();
    
            $(".btn-primary").click(function () {
                if (isClose) {
                    ws = new WebSocket("ws://localhost:8181");
                }
                updataSource();
            });
            $(".btn-danger").click(function () {
                ws.close();
            });
    
            ws.onclose = function (e) {
                console.log("断开连接", e);
                isClose = true;
            };
        </script>
    </body>
    
    </html>

    服务端代码

    var WebSocketServer = require('ws').Server,
        wss = new WebSocketServer({
            port: 8181
        }); //服务端口8181
    var speed = {
        "A11111": 95.0,
        "A22222": 50.0
    }
    
    var randomSpeedUpdater = function () {
        for (var item in speed) {
    
            var randomizedChange = Math.random(60, 120);
            speed[item] += randomizedChange;
    
        }
    }
    //模拟车速实时变化
    
    setInterval(
        function () {
            randomSpeedUpdater();
        }, 1000)
    
    var clientSpeeds = [];
    wss.on('connection', function (ws) {
        var sendSpeedUpdates = function (ws) {
            if (ws.readyState == 1) {
                var speedObj = {};
                for (var i = 0; i < clientSpeeds.length; i++) {
                    var item = clientSpeeds[i];
                    speedObj[item] = speed[item];
                }
                if (speedObj.length !== 0) {
                    ws.send(JSON.stringify(speedObj)); //需要将对象转成字符串。WebSocket只支持文本和二进制数据,推送消息
                    console.log("服务器:更新数据", JSON.stringify(speedObj));
                }
    
            }
        }
    
        //每三秒发送一次
        var clientSpeedUpdater = setInterval(function () {
            sendSpeedUpdates(ws);
        }, 3000);
        ws.on('message', function (message) {
            var stockRequest = JSON.parse(message); //根据请求过来的数据来更新。
            console.log("服务器:收到消息", stockRequest);
            clientSpeeds = stockRequest['speed'];
            sendSpeedUpdates(ws);
        });
        ws.on('close', function () {
            if (clientSpeedUpdater > 0) {
                //断开连接清楚定时器
                clearInterval(clientSpeedUpdater);
            }
        });
    });

    启动服务,效果截图(我用的pm2管理进程,可以直接node启动)

    3.3简单实现聊天场景(待续。。。)

  • 相关阅读:
    my first android test
    VVVVVVVVVV
    my first android test
    my first android test
    my first android test
    ini文件
    ZZZZ
    Standard Exception Classes in Python 1.5
    Python Module of the Week Python Module of the Week
    my first android test
  • 原文地址:https://www.cnblogs.com/zzghk/p/10573437.html
Copyright © 2011-2022 走看看