hello websocket

作者: snow_in | 来源:发表于2018-11-17 21:34 被阅读0次

最近在做一个实时的项目,其中一个重要的功能就是实时的从后端获取数据。当时就是有两种方案去实现这个功能,一种是浏览器定时向服务器发送请求,服务器接到请求后返回最新的数据(轮询),还有就是使用H5新增的通信协议webSocket。

其实之前有用过轮询的方式做一些东西,它最大的问题就是返回结果的间隔不是我们想要的。比如

setInterval(function() {
    $.get("/xxx", function(data, status) {
        console.log(data);
    });
}, 2000);

上面的程序是每2秒向后台发送一次请求。我们想要的结果是2秒就可以接收一次数据,根据js事件循环机制我们知道,setInterval只是在规定的时间间隔内向任务队列插入了回调函数,但是不会立即执行,这就会导致每次返回结果的时间并不是恰好隔着2秒。

还有一个问题就是浏览器频繁地向服务器发送请求,可能数据并没有更新,这样就造成很多无用的请求,浪费带宽。

websocket的简单介绍

websocket是一个双向通信的协议,连接建立后,服务器和客户端都能主动地向对方发送和接收数据。Websocket使用ws或wss的统一资源标志符,和http、https类似,wss就是对通信进行加密。

1. 握手协议

建立websocket连接,是需要先通过HTTP/1.1协议的101状态码进行握手的。看一下它的握手请求:


websocket.png

其中最重要的就是
Connection: Upgrade
Upgrade: websocket
表示连接升级到websocket协议。
Sec-WebSocket-Version 表示支持的websocket版本
Sec-WebSocket-Key 主要用来生成响应头中Sec-WebSocket-Accept的值

2、优点

对于websocket的优点,我们看一下维基百科里面的介绍(websocket):

  • 较少的控制开销。在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较少。在不包含扩展的情况下,对于服务器到客户端的内容,此头部大小只有2至10字节;对于客户端到服务器的内容,此头部还需要加上额外的4字节的掩码。相对于HTTP请求每次都要携带完整的头部,此项开销显著减少了。
  • 更强的实时性。由于协议是全双工的,所以服务器可以随时主动给客户端下发数据。相对于HTTP请求需要等待客户端发起请求服务端才能响应,延迟明显更少
  • 保持连接状态。与HTTP不同的是,Websocket需要先创建连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息。而HTTP请求可能需要在每个请求都携带状态信息(如身份认证等)。
  • 更好的二进制支持。
  • 可以支持扩展。Websocket定义了扩展,用户可以扩展协议、实现部分自定义的子协议。如部分浏览器支持压缩等
  • 更好的压缩效果。相对于HTTP压缩,Websocket在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的数据时,可以显著地提高压缩率。

使用

const ws = new WebSocket(`ws://example.com/newEnergyWebSocket`);
       
        ws.onopen = (evt) => { // 连接成功后的回调函数
          console.log('Connection open ...', ws.readyState);
          if (ws.readyState === 1) {
            ws.send(1); // 向服务器发送数据,可以在这里传递接口参数
          }
        };

        ws.onmessage = (evt) => { // 收到数据后的回调函数
          console.log('Received Message: ');
         // 接收数据
        };

       ws.onclose = (evt) => { // 连接关闭后的回调函数
          console.log('Connection closed.');
        };

webSocket.readyState返回当前实例的连接状态:

  • CONNECTING:值为0,表示正在连接。
  • OPEN:值为1,表示连接成功,可以通信了。
  • CLOSING:值为2,表示连接正在关闭。
  • CLOSED:值为3,表示连接已经关闭,或者打开连接失败。
    连接建立后就可以接收数据了:


    websocket2.png

要想关闭连接调用close方法:

 ws.close()

后端用的公司的框架,一开始因为tomcat版本太低一直报错:


websocket1.png

后来升级到7.0.7之后就好了。

相关文章

网友评论

    本文标题:hello websocket

    本文链接:https://www.haomeiwen.com/subject/mhlifqtx.html