zoukankan      html  css  js  c++  java
  • JavaScript WebSocket 使用总结

    翻看之前写的 Highcharts使用总结  和 前后台交互之传参方式,想对 WebSocket 单独写一个使用总结。

    一、认识 WebSocket 。

    WebSocket 是 H5 新出的一种协议,为解决客户端与服务端实时通信而产生的技术。

    通过 HTTP/HTTPS 协议进行三次握手后创建一个用于交换数据的 TCP连接,此后服务端与客户端通过此 TCP 连接进行实时通信,任意时刻都可以相互推送消息,也允许跨域通信。(三.2)

    比较:Ajax 轮询方式,客户端隔一段时间询问服务器,看是否有数据,是客户端主动请求的。

              XHR 受到域的限制。

              Long Poll 长轮询原理跟 Ajax 差不多,都是轮询方式,不过采取的是阻塞模型,即客户端发起连接后,如果没消息,就一直不返回Response给客户端,直到有消息才返回,返回完之后,客户端再次建立连接,周而复始。

    二、简明入门。

    1、创建一个新的 WebSocket 对象:

    var Socket = new WebSocket(url,[protocal]);

    参数解释: (1)url : 要连接的URL ; (2)[protocal] : 可选,指定一个服务器支持的协议。

    2、WebSocket 属性:

    (1) Socket.readyState —— readyState 代表 ReadOnly 属性的状态。

             取值:0 —— 连接尚未建立;

                       1 —— 连接已经建立;

                       2 —— 连接正在关闭;

                       3 —— 连接已经关闭或不可用。

    (2)Socket.bufferedAmount —— 读属性的 bufferedAmount 代表文本的字节数,utf-8 的排列使用 send() 方法。

    3、WebSocket 事件:

    事件 处理程序 说明
    open Socket.onopen 发生在套接字建立连接
    message Socket.onmessage 发生时客户端收到来自服务器的数据
    error Socket.onerror 发生时有通信错误
    close Socket.onclose 发生在连接关闭

    4、WebSocket 方法:

    (1)Socket.send() —— send(data) 方法用来连接传输数据;

    (2)Socket.close() —— close()方法将被用于终止任何现有连接。

    三、用法示例。

    <a href="javascript:WebSocketTest()">点击运行WebSocket</a>
    function WebSocketTest()
            {
                if ("WebSocket" in window)
                {
                    alert("WebSocket is supported by your Browser!");
                    // 打开WebSocket
                    var ws = new WebSocket("ws://127.0.0.1:2012");
                    ws.onopen = function()
                    {
                        // Web Socket is connected, send data using send()
                        ws.send("121314");
                        alert("Message is sending");
                    };
                    ws.onmessage = function (evt)
                    {
                        var received_msg = evt.data;
                        alert("Message is received");
                    };
                    ws.onclose = function()
                    {
                        // websocket is closed
                        alert("Connection is closed");
                    };
                } else {
                    // The browser doesn't support WebSocket
                    alert("WebSocket NOT supported by your Browser!!!");
                }
            }

    四、项目实例。

    项目用于物流仓库,管理仓库货架货位、货位灯、出库入库统计以及仓库实时温湿度统计显示。采用 WebSocket 和服务器连接,获取接口数据比较方便。

    页面有显示“服务器状态”的红绿色圆形:

    <div class="pull-right">
         <span>服务器状态:</span>
         <span id="wsServerStatus">未连接</span>
         <div id="sx" style="12px;height:12px;border-radius:6px;background-color:red;" class="inline"></div>
     </div>

    红色代表“未连接”,绿色代表“连接”。

    页面加载时建立连接:

    <script>
            var ws;
            var SocketCreated = false;
    
            window.onload = function Connect() {
                if (SocketCreated || (ws.readyState == 0 || ws.readyState == 1)) {
                    // readyState属性表示ReadOnly属性的状态。等于0或者1表示连接未建立
                    SocketCreated = false;
                    ws.close();
                    document.getElementById("wsServerStatus").innerHTML = "连接未建立";
                    document.getElementById("sx").style.background = "red";
                } else {
                    document.getElementById("wsServerStatus").innerHTML = "准备连接到服务器 ...";
                    if ("WebSocket" in window) {
                        ws = new WebSocket("ws://192.168.1.108:2012");
                    }else if("MozWebSocket" in window) {
                        ws = new MozWebSocket("ws://192.168.1.108:2012");
                    }
                    SocketCreated = true;
                    ws.onopen = WSonOpen;
                    ws.onmessage = WSonMessage;
                    ws.onclose = WSonClose;
                    ws.onerror = WSonError;
                }
            };
    
            function WSonOpen() {
                document.getElementById("wsServerStatus").innerHTML = "连接已建立";
                document.getElementById("sx").style.background = "green";
            };
    
            function WSonMessage(event) {
                var msg = JSON.parse(event.data);
                switch (msg.key) {
                    case "/device/data":
                    case "/device/status":
                        var n = document.getElementById("content-main").childElementCount;
                        for (var i = 1; i < n; i++) {
                            try{
                                var m = document.getElementById("content-main").children[i];
                                m.contentWindow.ParseValue(msg.body);
                            }catch(err){
                                alert("error:" + err);
                            }
                        }
                        break;
                }
            };
    
            function WSonClose() {
                document.getElementById("wsServerStatus").innerHTML = "连接已关闭";
                document.getElementById("sx").style.background = "red";
            };
    
            function WSonError() {
                document.getElementById("wsServerStatus").innerHTML = "远程连接中断";
                document.getElementById("sx").style.background = "red";
            };
    
            function WsSend(val) {
                ws.send(val);
            }
    
        </script>
    View Code

    五、WebSocket 小应用——聊天室

    因为这是去年做的一个小东西,当时的公司后台帮我写了个聊天服务器,所以可以正常使用这个聊天室,挺好玩的,可以相互发送消息,但是现在我这里只有前端的(⊙o⊙)…

    <div class="talk_div">
        <div id="skm_LockPane" class="LockOff"></div>
        <header id="form1" runat="server">
            <h2>聊天室</h2>
            <h4>点击连接按钮,会通过WebSocket发起连接,进行会话</h4>
        </header>
        <div class="talk_container">
            <form>
                服务器地址:<input type="text" id="Connection"><br>&nbsp;&nbsp;名:<input type="name" id="txtName">&nbsp;&nbsp;
                <button id="ToggleConnection" type="button" onclick="ToggleConnectionClicked();">连接</button>
            </form>
            <div id="LogContainer" class="container"></div>
        </div>
        <footer id="SendDataContainer">
            <input type="text" id="DataToSend" size="70">
            <input type="button" id="SendData" value="发送" onclick="SendDataClicked();">
        </footer>
    </div>
    View Code
    var ws;
    var SocketCreated = false;
    var isUserloggedout = false;
    
    function lockOn(str) {
        var lock = document.getElementById('skm_LockPane');   // id="skm_LockPane"  空idv
        if (lock)   // 如果变量lock
            lock.className = 'LockOn';
        lock.innerHTML = str;
    }
    
    function lockOff() {
        var lock = document.getElementById('skm_LockPane');
        lock.className = 'LockOff';
    }
    
    /* 点击 按钮 */
    function ToggleConnectionClicked() {
        if (SocketCreated && (ws.readyState == 0 || ws.readyState == 1)) {
            //(SocketCreated = false)&&(连接未建立)。。。。readyState属性表示ReadOnly属性的状态。等于0或者1表示连接未建立
            lockOn("离开聊天室...");      //  lockOn  页面秒弹"离开聊天室..."
            SocketCreated = false;
            isUserloggedout = true;
            ws.close();
        } else {
            lockOn("进入聊天室...");   //  lockOn  页面秒弹"进入聊天室..."
            Log("准备连接到服务器 ...");
            try {
                if ("WebSocket" in window) {
                    ws = new WebSocket("ws://" + document.getElementById("Connection").value);
                }
                else if ("MozWebSocket" in window) {
                    ws = new MozWebSocket("ws://" + document.getElementById("Connection").value);
                }
                SocketCreated = true;
                isUserloggedout = false;
            } catch (ex) {
                Log(ex, "ERROR");
                return;
            }
            document.getElementById("ToggleConnection").innerHTML = "断开";
            ws.onopen = WSonOpen;
            ws.onmessage = WSonMessage;
            ws.onclose = WSonClose;
            ws.onerror = WSonError;
        }
    };
    
    
    function WSonOpen() {
        lockOff();
        Log("连接已建立!", "OK");
        $("#SendDataContainer").show();              //输入框显现
        console.log(1213);   //控制台输出
    };
    
    function WSonMessage(event) {
        Log(event.data);
    };
    
    function WSonClose() {
        lockOff();
        if (isUserloggedout)
            Log("【" + document.getElementById("txtName").value + "】离开了聊天室!");
        document.getElementById("ToggleConnection").innerHTML = "连接";
        $("#SendDataContainer").hide();
    };
    
    function WSonError() {
        lockOff();
        Log("远程连接中断", "ERROR");
    };
    
    
    function SendDataClicked() {
        if (document.getElementById("DataToSend").value.trim() != "") {
            ws.send(document.getElementById("txtName").value + " 说:" + document.getElementById("DataToSend").value);
            document.getElementById("DataToSend").value = "";
        }
    };
    
    
    function Log(Text, MessageType) {
        if (MessageType == "OK") Text = "<span style='color: green;'>" + Text + "</span>";
        if (MessageType == "ERROR") Text = "<span style='color: red;'>" + Text + "</span>";
        document.getElementById("LogContainer").innerHTML = document.getElementById("LogContainer").innerHTML + Text + "<br />";
        var LogContainer = document.getElementById("LogContainer");
        LogContainer.scrollTop = LogContainer.scrollHeight;
    };
    
    
    $(document).ready(function () {
        $("#SendDataContainer").hide();
        var WebSocketsExist = true;
        try {
            var dummy = new WebSocket("ws://192.168.1.201:2012");
        } catch (ex) {
            try {
                webSocket = new MozWebSocket("ws://192.168.1.201:2012");
            }
            catch (ex) {
                WebSocketsExist = false;
            }
        }
    
        if (WebSocketsExist) {
            Log("您的浏览器支持WebSocket. 您可以尝试连接到聊天服务器!", "OK");
            document.getElementById("Connection").value = "192.168.1.201:2012";
        } else {
            Log("您的浏览器不支持WebSocket。请选择其他的浏览器再尝试连接服务器。", "ERROR");
            document.getElementById("ToggleConnection").disabled = true;
        }
    
        $("#DataToSend").keypress(function (evt) {
            if (evt.keyCode == 13) {
                $("#SendData").click();
                evt.preventDefault();
            }
        })
    });
    View Code

    输入用户名之后点击按钮连接到服务器:

    因为没有服务器可以连接,所以。。。。O(∩_∩)O哈哈~

    在点击断开后,连接断开,用户离开:

    前端后台都会的可以玩一下,我刚开始的时候觉得好好玩,一直在那发消息哈哈~

    六、 WebSocket 其他 。

    1、所谓的 TCP 连接,即三次握手,还记得在学校的时候期末考试这个必考,啊哈哈

    过程:(1)客户端发送一个SYN包给服务器,然后等待应答。

               (2)服务器端回应给客户端一个ACK=1、SYN=1的 TCP 数据段。

               (3)客户必须再次回应服务器端一个ACK确认数据段。

    2、WebSocket 和 Http 协议。

      WebSocket 和 Http 协议都属于应用层协议。

      关系:当 WebSocket 建立握手连接时,数据是通过 HTTP 协议传输的,在建立连接后,真正的数据传输不需要 HTTP 协议参与。

    3、WebSocket Server (web 服务器)

    调用开源库,如 PyWebSocket(python语言)、WebSocket-Node(js语言,建立在Node.js上)、LibWebSockets(c/c++语言)....他们实现了 WebSocket 数据包的封装和解析,调用这些接口即可。

  • 相关阅读:
    【PENNI】2020-ICML-PENNI: Pruned Kernel Sharing for Efficient CNN Inference-论文阅读
    【BlockSwap】2020-ICLR-BlockSwap: Fisher-guided Block Substitution for Network Compression on a Budget-论文阅读
    【MCUNet】2020-NIPS-MCUNet Tiny Deep Learning on IoT Devices-论文阅读
    【FSNet】2020-ICLR-FSNet Compression of Deep Convolutional Neural Networks by Filter Summary-论文阅读
    【Shape Adaptor】2020-ECCV-Shape Adaptor: A Learnable Resizing Module-论文阅读
    【FairNAS】2019-arxiv-FairNAS Rethinking Evaluation Fairness of Weight Sharing Neural Architecture Search-论文阅读
    【EagleEye】2020-ECCV-EagleEye: Fast Sub-net Evaluation for Efficient Neural Network Pruning-论文阅读
    【DMC】2020-CVPR-Discrete Model Compression with Resource Constraint for Deep Neural Networks-论文阅读
    【RegNet】2020-CVPR-Designing Network Design Spaces-论文阅读
    【DropNet】2020-ICML-DropNet Reducing Neural Network Complexity via Iterative Pruning-论文阅读
  • 原文地址:https://www.cnblogs.com/lyr1213/p/7280321.html
Copyright © 2011-2022 走看看