JavaScript中WebSocket介绍与运用

来源:互联网 发布:mysql 等于符号 编辑:程序博客网 时间:2024/06/05 15:42

前言

本文重点在于websocket技术在JavaScript中的运用做介绍,对于其理论知识,再次并不多做介绍.主要是看websocket怎么在JavaScript中编写实例.

在 Web 应用程序中使用 WebSocket API案例:

https://netbeans.org/kb/docs/javaee/maven-websocketapi_zh_CN.html


1、Web Sockets简介

要说最令人津津乐道的新浏览器API,就得数Web Sockets了.Web Sockets的目标是在一个单独的持久连接上提供全双工以及双向通信.在JavaScript中创建了Web Sockets之后,会有一个HTTP请求发送到服务器以发起连接.在取得服务器响应后,建立的连接会使用HTTP升级从HTTP协议交换为Web Sockets协议.也就是说,使用标准的HTTP服务器无法实现Web Sockets,只有支持这种协议的专门服务器才能正常工作.

由于Web Sockets使用了自定义的协议,所以URL模式也略有不同.未加密的连接不再是http://,而是ws://;加密的连接也不是https://,而是wss://.在使用Web SocketURL时,必须带着这个模式,因为将来还有可能支持其他模式.

使用自定义协议而非HTTP协议的好处是,能够在客户端和服务端之间发送少量的数据,而不必担心HTTP那样字节级的开销.由于传递的数据包很小,因此Web Sockets非常使用移动应用.毕竟对移动应用而言,带宽和网络延迟都是关键问题.使用自定义协议的缺点在于,指定协议的时间比指定JavaScript API的时间还长.Web Sockets曾几度搁浅,就因为不断有人发现这个心协议存在一致性和安全性的问题.Firefox4 和Opera11都曾默认启用Web Sockets,但是在发布前夕有禁用掉了,因为有发现了安全隐患.目前支持Web Sockets的浏览器有Firefox6+,Safari5+,Chrome和iOS 4+版Safari.

WebSocket与TCP、HTTP的关系WebSocket与http协议一样都是基于TCP的,所以他们都是可靠的协议,Web开发者调用的WebSocket的send函数在browser的实现中最终都是通过TCP的系统接口进行传输的。

WebSocket和Http协议一样都属于应用层的协议,那么他们之间有没有什么关系呢?答案是肯定的,WebSocket在建立握手连接时,数据是通过http协议传输的,但是在建立连接之后,真正的数据传输阶段是不需要http协议参与的。

这里写图片描述

2、JavaScript中的websocket技术运用

在js文件当中运用websocket之前先检查当前浏览器是否支持websocket。固定下面代码:

//检查浏览器是否支持WebSocketif(window.WebSocket){    console.log('This browser supports WebSocket');}else{    console.log('This browser does not supports WebSocket');}

给一个websocket一般开发的时候会用的一些方法使用模板,代码来源:

https://www.cnblogs.com/tinywan/p/5894403.html

<!DOCTYPE html>  <meta charset="utf-8" />  <title>WebSocket Test</title>  <script language="javascript"type="text/javascript">      var wsUri ="ws://echo.websocket.org/";     var output;      function init() {         output = document.getElementById("output");         testWebSocket();     }      function testWebSocket() {         /**         * 创建一个WebSocket对象         * url注意事项上面已经说过在此在提醒一下:         * 参数是需要连接的服务器端的地址,同http协议使用http://开头一样         * WebSocket协议的URL使用ws://开头         * 另外安全的WebSocket协议使用wss://开头。         */        websocket = new WebSocket(wsUri);         /**         * WebSocket对象一共支持四个消息 onopen, onmessage, onclose和onerror         * 我们可以看出所有的操作都是采用消息的方式触发的,这样就不会阻塞UI,         * 使得UI有更快的响应时间,得到更好的用户体验。         */        /**         * 当Browser和WebSocketServer连接成功后,会触发onopen消息;         */        websocket.onopen = function(evt) {             onOpen(evt)         };         /**         * 当Browser接收到WebSocketServer端发送的关闭连接请求时,就会触发onclose消息。         */        websocket.onclose = function(evt) {             onClose(evt)         };         /**         * 当Browser接收到WebSocketServer发送过来的数据时,就会触发onmessage消息,         * 参数evt中包含server传输过来的数据;         */        websocket.onmessage = function(evt) {             onMessage(evt)         };         /**         * 如果连接失败,发送、接收数据失败或者处理数据出现错误,browser会触发onerror消息;         */        websocket.onerror = function(evt) {             onError(evt)         };     }      function onOpen(evt) {         writeToScreen("CONNECTED");         doSend("WebSocket rocks");     }      function onClose(evt) {         writeToScreen("DISCONNECTED");     }      function onMessage(evt) {         writeToScreen('<span style="color: blue;">RESPONSE: '+ evt.data+'</span>');         websocket.close();     }      function onError(evt) {         writeToScreen('<span style="color: red;">ERROR:</span> '+ evt.data);     }      function doSend(message) {         writeToScreen("SENT: " + message);          websocket.send(message);     }      function writeToScreen(message) {         var pre = document.createElement("p");         pre.style.wordWrap = "break-word";         pre.innerHTML = message;         output.appendChild(pre);     }      window.addEventListener("load", init, false);  </script>  <h2>WebSocket Test</h2>  <div id="output"></div>  </html>

再次给出一个实际代码使用样例,可以参照自己的需求更改上述模板代码:

 getWebSocket() {    const that = this;    if (this.httpPort === '') return false;    const url = `ws://localhost:${this.httpPort}/ws`;    let websocket;    if ('WebSocket' in window) {      websocket = new WebSocket(url);    }    websocket.onopen = () => {      websocket.send(JSON.stringify({        id: 'login_request',        token: window.identify(),      }));    };    websocket.onmessage = (evt) => {      const resultData = JSON.parse(evt.data);      // 依据id来判断是否是验证登录响应      /**       *       */      if (resultData.id === 'login_response') {        if (resultData.error_no !== '0') {          console.log(resultData.error_string);          websocket.close();        } else {          websocket.send(JSON.stringify({            id: 'query_log_request',            user_data: `localhost:${that.httpPort}`,            services: that.form.module,            begin_time: that.form.startTime,            end_time: that.form.endTime,            level_above: that.form.level,            key: that.form.key,            offset: that.offset,            count: that.count,          }));        }      }      if (resultData.error_no !== '0') {        that.$message.error(resultData.error_string);        return false;      }      // 刷新日志内容展示和下载日志文件      if (resultData.id === 'query_log_response') {        if (resultData.error_no === '0') {          // 查询日志成功标志          // 对返回的时间进行多时区时间时间到本地时间转换          const logsArray = [];          resultData.logs.forEach((log, i) => {            const utcSign = log.time.substring(10);            if (utcSign.indexOf('+') !== -1 || utcSign.indexOf('-') !== -1 || utcSign.indexOf('Z') !== -1) {              // const standTime = parseTimezoneString(log.time);              // Object.assign(log, { time: standTimeToYMDAndHMSTime(standTime) });              // log.time = standTimeToYMDAndHMSTime(standTime);              if (that.sign === 'downLogFile') {                logsArray[i] = `${log.time} [${log.component}] [${log.module}] [${log.level}] ${log.log}`;              }            }          });          // 下载文件功能          if (that.sign === 'downLogFile') {            that.sign = '';            const blob = new Blob(logsArray, { type: 'text/plain;charset=utf-8' });            const logFileTime = new Date();            const logFileName = `${logFileTime.getFullYear()}-${(logFileTime.getMonth() + 1)}-${logFileTime.getDate()} ${logFileTime.getHours()}:${logFileTime.getMinutes()}:${logFileTime.getSeconds()}.log`;            FileSaver.saveAs(blob, logFileName);          } else {            if (resultData.is_last) {              that.isLastPage = true;            } else {              that.isLastPage = false;            }            that.tableData = resultData.logs;          }        } else {        // 查实日志失败的情况(渲染一个空的历史查询界面)          that.tableData = [];        }      }      return true;    };    websocket.onerror = () => {      console.log('webSocket Error!!!');      websocket.close();    };    return false;  }
原创粉丝点击