WebSocket

背景介绍

早期,很多网站为了实现推送技术,所用的技术都是轮询(也称为短轮询)。轮询是指浏览器每隔一段时间向服务器发送 HTTP 请求,然后服务器返回最新的数据给客户端。

常见的轮询方式分为轮询和长轮询,他们的区别如下图所示:

为了更加直观的感受轮询与短轮询之间的区别,我们来看一下具体代码:

短轮询的方式有一个明显的缺点,即浏览器需要不断的向服务器发出请求,然而 HTTP 请求与响应可能会包含较长的头部,其中真正有效的数据可能只是一小部分,所以这样会浪费很多的带宽资源。

在下棋游戏过程中轮询操作就会出现下图情况,

很明显,像这样的轮询操作,开销是比较大的,而且成本也比较高。如果轮询间隔时间太长,玩家1 落子之后,玩家2 就不能及时拿到结果,如果轮询间隔时间太短,虽然即时性得到改善,但是玩家2 会多次发送请求,这将会浪费更多的机器资源。

WebSocket简介

websocket 是一种网络传输协议,可在单个 TCP 连接上进行全双工通信,位于 OSI 模型的应用层。

websocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 websocket API中,浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输

接下来我们用一张图看一下 XHR Polling(短轮询)与 websocket 之间的区别。

websocket 优点

  1. 较少的控制开销,在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据报头部相对较小。
  2. 更强的实时性,由于协议是全双工的,所以服务器可以随时主动给客户端下发数据。相对于 HTTP 请求需要等待客户端发起请求,服务端才能响应,延迟明显更少。
  3. 保持连接状态,与 HTTP 不同的是,websocket 需要先创建连接,这就使得其成为一种有状态的协议(之后通信时可以省略部分状态信息)。
  4. 更好的二进制支持,websocket 定义了二进制帧,相对 HTTP 而言,可以更轻松的处理二进制内容。
  5. 可以支持扩展,websocket 定义了扩展,用户可以扩展协议、实现部分自定义的子协议。

WebSocket报文格式

websocket也是一个应用层协议,下层是基于TCP的。

**FIN:**标识是否结束

**RSV:**保留位,未来可能会用到,但是现在没有用

**opcode:**描述了当前 websocket 报文的类型,(文本帧、二进制帧、ping帧、pong帧...)

**payload len:**表示的是当前数据报携带的数据载荷的长度,这个字段本身就是一个变长的,一个 websocket 数据报能承载的载荷长度是非常非常长的。

**payload data:**实际报文要传输的数据载荷

WebSocket握手过程(建立连接的过程)

使用网页端,尝试和 服务器建立 websocket 连接。网页端首先给服务器发送一个 HTTP 请求,这个 HTTP 请求中会带有特殊的 header

Connection:Upgrade

Upgrade:Websocket

这两个 header 的作用就是告诉服务器,我要进行协议升级。

如果服务器支持 websocket,就会返回一个特殊的 HTTP 响应,这个响应的状态码是 101(切换协议)。然后客户端和服务器之间就开始使用 websocket 来进行通信了。

WebSocket示例

java 复制代码
@Component
public class TestAPI extends TextWebSocketHandler {
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        System.out.println("连接成功");
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        System.out.println("收到信息:" + message.getPayload());
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        System.out.println("连接异常");
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        System.out.println("连接关闭");
    }
}

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    @Autowired
    private TestAPI testAPI;

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(testAPI, "/test");
        
    }

}

**afterConnectionEstablished:**WebSocket 建立连接之后执行

**handleTextMessage:**收到前端发送的信息之后执行,可以处理接收的信息

**handleTransportError:**传输过程中遇到错误时执行

**afterConnectionClosed:**连接关闭之后执行,可以释放一些不需要的资源

相关推荐
小堃学编程7 小时前
计算机网络(十) —— IP协议详解,理解运营商和全球网络
网络·tcp/ip·计算机网络
IPFoxy66610 小时前
探索路由器静态IP的获取方式
网络·智能路由器
menge233310 小时前
VLAN:虚拟局域网
网络·智能路由器
GZ_TOGOGO10 小时前
【2024最新】华为HCIE认证考试流程
大数据·人工智能·网络协议·网络安全·华为
ZachOn1y10 小时前
计算机网络:计算机网络概述 —— 初识计算机网络
网络·计算机网络·知识点汇总·考研必备
三金1213811 小时前
SpringIoC容器的初识
网络·网络协议·rpc
狼头长啸李树身12 小时前
眼儿媚·秋雨绵绵窗暗暗
大数据·网络·服务发现·媒体
SizeTheMoment13 小时前
初识HTTP协议
网络·网络协议·http
哲伦贼稳妥13 小时前
一天认识一个硬件之机房地板
运维·网络·经验分享·其他
hgdlip15 小时前
如何快速切换电脑的ip地址
网络·tcp/ip·电脑