快速了解Websocket技术

一、什么是Websocket技术?

WebSocket是一种全双工网络通信协议,它提供了在单个TCP连接上进行全双工通信的渠道。WebSocket使得客户端(通常是浏览器)和服务器之间可以进行持续的双向数据交换。传统的HTTP协议是请求/响应模式,即客户端发起请求后,等待服务器响应;而WebSocket允许服务器主动向客户端推送信息,同时也允许客户端与服务器进行实时通信。

二、为什么需要使用Websocket技术?

  1. 实时通信:WebSocket支持服务器端主动向客户端推送信息,这对于需要实时更新数据的应用非常重要,比如即时通讯、在线协作工具、实时股票报价等。

  2. 减少延迟:与轮询或其他长轮询技术相比,WebSocket可以显著降低延迟。因为不需要客户端频繁地向服务器发送请求来检查是否有新的数据,而是服务器可以随时主动推送数据给客户端。

  3. 持久连接:WebSocket连接是一直保持开启状态的,这意味着一旦连接建立,就无需重复建立连接。因此,可以大大减少建立和断开连接的开销,并且实现更低的延迟和更高的吞吐量。

  4. 全双工通信:WebSocket支持客户端和服务器同时发送数据,这意味着两者可以同时发送消息而不会互相干扰,这一点对于需要双向实时互动的应用至关重要。

  5. 更好的用户体验:由于上述优点,使用WebSocket的应用程序可以提供更快的响应速度和更流畅的用户聊天体验。

三、WebSocket与HTTP的区别

WebSocket和http都是基于TCP的应用层协议,使用的也是 80 端口(若运行在 TLS 之上时,默认使用 443 端口)。WebSocket的协议标识符是ws,加密是wws,http的协议标识符是http,加密是https。

其区别主要就在于连接的性质和通信方式:

  1. WebSocket是一种全双工双向通信的协议,通过一次握手即可建立持久性的连接,服务器和客户端可以随时发送和接收数据,http是半双工通信协议。

  2. 而HTTP协议是一种请求-响应模式的协议,每次通信都是只能客户端发送消息给服务端,然后服务端响应请求。服务端不能主动发送消息给客户端

  3. WebSocket的实时性更好,延迟更低,并且在服务器和客户端之间提供双向的即时通信能力,适用于需要实时数据传输的场景。

四、Http协议升级到Websocket的过程

过程图如下:

在这里插入图片描述

Websocket请求报文:

// websocket握手:客户端发送的请求头
GET wss://www.example.cn/webSocket HTTP/1.1  // 使用的https协议, 对应的wss请求
Host: www.example.cn
Connection: Upgrade  // 带upgrade头的http1.1消息必须含有connection头,表示任何接受此消息的人都在转发此消息之前处理掉connection中指定的域(即不转发upgrade域)
Upgrade: websocket  				// 定义转换协议的header域,如果服务器支持,客户端希望使用已经建立好的http(tcp)连接
Sec-WebSocket-Version: 13 	// 客户端支持的WebSocket协议的版本列表
Origin: http://example.cn 	// Origin为安全使用,防止跨站攻击,浏览器一般会使用这个来标识原始域,类似于Referer。但与Referer 不同的是,Origin 只包含了协议和主机名称
Sec-WebSocket-Key: afmbhhBRQuwCLmnWDRWHxw== // 客户端随机生成的字符串,服务器会使用此字段组装成另一个key值(构造出一个SHA-1 的信息摘要)放在握手返回信息里,用于客户端到服务器websocket的初始握手,避免夸协议攻击
Sec-WebSocket-Protocol: chat, superchat 		// 首标,告诉客户端应用程序可使用的协议
Sec-WebSocket-Extensions: permessage-deflate // 首标,permessage-deflate:协商使用传输数据压缩,client_max_window_bits:擦采用LZ77压缩算法时,滑动窗口相关SIZE大小

// websocket握手:服务器发出的响应头
HTTP/1.1 101 // 服务端响应101状态码、Upgrade和Sec-WebSocket-Accept首标才算连接成功,否则不能连接成功。
Server: nginx/1.12.2
Date: Sat, 11 Aug 2018 13:21:27 GMT
Connection: upgrade // 指定一项或多项协议名,按优先级排序,以逗号分隔,这里表示升级为 WebSocket 协议
Upgrade: websocket
Sec-WebSocket-Accept: sLMyWetYOwus23qJyUD/fa1hztc= // 根据Sec-WebSocket-Key加上特殊字符串,计算SHA-1摘要,再进行 Base64编码协议生成(可尽量避免普通HTTP请求被误认为WebSocket协议)
Sec-WebSocket-Protocol: chat
Sec-WebSocket-Extensions: permessage-deflate;client_max_window_bits=15

在这里插入图片描述
过程分析:

为了建立一个 WebSocket 连接,客户端浏览器首先要向服务器发起一个 HTTP 请求,这个请求和通常的 HTTP 请求不同,包含了一些附加头信息,其中附加头信息"Upgrade: WebSocket"表明这是一个申请协议升级的 HTTP 请求,服务器端解析这些附加的头信息然后产生101状态码应答信息返回给客户端,客户端和服务器端的 WebSocket 连接就建立起来了,双方就可以通过这个连接通道自由的传递信息,并且这个连接会持续存在直到客户端或者服务器端的某一方主动的关闭连接。

五、常见应用场景

实时聊天:WebSocket能够提供双向、实时的通信机制,使得实时聊天应用能够快速、高效地发送和接收消息,实现即时通信。
实时数据推送:用于实时数据推送场景,如新闻快讯、实时天气信息等,服务器可以实时将数据推送给客户端,确保数据的及时性和准确性。
多人在线游戏:实时的双向通信机制,适用于多人在线游戏应用,使得游戏服务器能够实时地将游戏状态和玩家行为传输给客户端,实现游戏的实时互动。
在线客服:WebSocket可以用于在线客服和客户支持系统,实现实时的客户沟通和问题解决,提供更好的用户体验,减少等待时间。

六、简单示例

let socketUrl = 'ws://52.013.14.11:999/xuyuan';
      // 代表由一个聊天室跳到另外一个的时候需要清理当前浏览器的webwocket连接,重新建立
        if (socket != null) {
            socket.close();
            socket = null;
        }
        // 开启一个websocket服务
        /*WebSocket 升级请求:
         当创建 WebSocket 对象时,浏览器会自动发送一个特殊的 HTTP 请求到 指定的 URL,并申请升级到WebSocket*/
        socket = new WebSocket(socketUrl);
        //建立连接成功触发的函数
        socket.onopen = function () {
            startHeartbeat();
        };
// 浏览器会尝试与指定的服务器建立连接。如果连接成功建立,浏览器会触发 onopen 事件
socket.onmessage = (event) => {
  console.log("receive: ", event.data);
};
// 连接或通信过程中发生错误
socket.onerror = (event) => {
  console.log("errror: ", event.error);
};
// 与服务器断开连接
socket.onclose = (event) => {
  console.log("close: ", event.code);
};

七、websocket心跳机制

示例代码:


let socket = null;
// 心跳包发送间隔时间
const heartbeatInterval = 30 * 1000; // 30秒
let heartbeatTimer = null;
let isConnect = false;
// 心跳包
const startHeartbeat = () => {
    heartbeatTimer = setInterval(() => {
        if (socket.readyState === WebSocket.OPEN) {
            socket.send("ping");
        }
    }, heartbeatInterval);
}

// 解除会话
const stopHeartbeat = () => {
    clearInterval(heartbeatTimer);
    heartbeatTimer = null;
}

// websocket重连
const reConnect = () => {
  // 如果已经连上就不在重连了
  if (isConnect) {
    return;
  }
  clearTimeout(reciveCode);
  // 延迟5秒重连 避免过多次过频繁请求重连
  reciveCode = setTimeout(() => {
    newWebSocket();
  }, 5000);
};

// webscoket升级的过程
 let socketUrl = 'ws://' + URL + '/websocket/' + uid + '/' + stats.value.team.teamId;
      // 代表由一个聊天室跳到另外一个的时候需要清理当前浏览器的webwocket连接,重新建立
        if (socket != null) {
            socket.close();
            socket = null;
        }
        // 开启一个websocket服务
        /*WebSocket 升级请求:
         当创建 WebSocket 对象时,浏览器会自动发送一个特殊的 HTTP 请求到 指定的 URL,并申请升级到WebSocket*/
        socket = new WebSocket(socketUrl);
        //发送心跳包, 用来维持当前的websocket
        socket.onopen = function () {
        // 表明连接成功
         isConnect = true;
            startHeartbeat();
        };
        //  浏览器端收消息,获得从服务端发送过来的文本消息
        socket.onmessage = function (msg) {
            // 用来进行心跳包
            if (msg.data === "pong") {
                return;
            }
              //关闭事件
        socket.onclose = function () {
          isConnect = false;
          // 解除会话
            stopHeartbeat();
            setTimeout(init, 5000); // 5秒后重连
        };
        //发生了错误事件
        socket.onerror = function () {
            Toast.fail("发生了错误")
              isConnect = false;
              reConnect();
        }
    }
            }

分析过程:

1、作用:使 WebSocket 连接保持长连接,避免断开连接的情况发生。同时,心跳机制也可以检查WebSocket连接的状态,及时处理异常情况。还可以减少WebSocket连接及服务器资源的消耗。

2、原理:是利用心跳包及时发送和接收数据,保证WebSocket长连接不被断开。

3、详细流程:

  • 客户端建立WebSocket连接成功。

  • 客户端向服务器发送心跳数据包(心跳包是指在一定时间间隔内,WebSocket发送的空数据包),服务器接收并返回一个表示接收到心跳数据包的响应。

  • 当服务器没有及时接收到客户端发送的心跳数据包并响应给客户端响应时,服务器会发送一个关闭连接的请求。

4、实现方式
使用startHeartbeat定时发送心跳包。对服务器造成很大的压力,因为即使WebSocket连接正常,也要定时发送心跳包,从而消耗服务器资源。
在前端监听到WebSocket的onclose()事件时,重新创建WebSocket连接。减轻了服务器的负担,但是在重连时可能会丢失一些数据。

5、WebSocket重连
重连意思就是在WebSocket断开之后重新建立连接,这里指由于异常断开需要重新连接。
常用实现方法有下:
1)前端监听WebSocket的onclose()事件,重新创建WebSocket连接。
2)使用WebSocket插件或库,例如Sockjs、Stompjs等。
3)使用心跳机制检测WebSocket连接状态,自动重连。
4)使用断线重连插件或库,例如ReconnectingWebSocket等。

6、通过WebSocket心跳机制,实现重连
思路: 在建立长连接的时候开启心跳 > 通过和服务端发送信息,得到服务端给返回的信息,然后重置心跳 > 清除时间,再重新开启心跳。(如果网络断开的话,会执行方法,重新连接)

八、补充示例说明(spring boot + Websocket技术整合)

如果有小伙伴需要进行我补充这个示例的,可以评论中告知我哦,我会看大家的需求量来进行补充。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值