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 数据包的封装和解析,调用这些接口即可。

  • 相关阅读:
    KnockoutJS 3.X API 第五章 高级应用(4) 自定义处理逻辑
    KnockoutJS 3.X API 第五章 高级应用(3) 虚拟元素绑定
    KnockoutJS 3.X API 第五章 高级应用(2) 控制后代绑定
    KnockoutJS 3.X API 第五章 高级应用(1) 创建自定义绑定
    KnockoutJS 3.X API 第四章(14) 绑定语法细节
    KnockoutJS 3.X API 第四章(13) template绑定
    KnockoutJS 3.X API 第四章 表单绑定(12) selectedOptions、uniqueName绑定
    KnockoutJS 3.X API 第四章 表单绑定(11) options绑定
    KnockoutJS 3.X API 第四章 表单绑定(10) textInput、hasFocus、checked绑定
    KnockoutJS 3.X API 第四章 表单绑定(9) value绑定
  • 原文地址:https://www.cnblogs.com/lyr1213/p/7280321.html
Copyright © 2011-2022 走看看