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简单实现聊天场景(待续。。。)

  • 相关阅读:
    git 创建一个空分支
    github page的两种类型
    hexo-theme-next
    github网页
    Linux下的CPU使用率与服务器负载的关系与区别
    mysql数据库优化日志(更)-howyue
    图片延时加载
    jQuery实现页面滚动时顶部动态显示隐藏
    TCP与UDP区别
    记一次网站服务器迁移(my)
  • 原文地址:https://www.cnblogs.com/zzghk/p/10573437.html
Copyright © 2011-2022 走看看