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:**连接关闭之后执行,可以释放一些不需要的资源

相关推荐
qq_429856573 小时前
计算机网络的五层结构(物理层、数据链路层、网络层、传输层、应用层)到底是什么?
网络·计算机网络
奋斗者1号7 小时前
《Crawl4AI 爬虫工具部署配置全攻略》
网络·爬虫
courniche8 小时前
VRRP与BFD在冗余设计中的核心区别:从“备用网关”到“毫秒级故障检测”
网络·智能路由器
艾厶烤的鱼8 小时前
架构-信息安全技术基础知识
网络·架构
muxue17810 小时前
centos 7 网络配置(2):ping命令出现问题
linux·网络·centos
高效匠人11 小时前
FastAPI + Redis Pub/Sub + WebSocket 组合解决方案的详细介绍
redis·websocket·fastapi
SQingL12 小时前
解决SSLError: [SSL: DECRYPTION_FAILED_OR_BAD_RECORD_MAC] decryption faile的问题
服务器·网络协议·ssl
山猪打不过家猪12 小时前
(六)RestAPI 毛子(外部导入打卡/游标分页/Refit/Http resilience/批量提交/Quartz后台任务/Hateoas Driven)
网络·缓存
weixin1382339517913 小时前
EN18031测试,EN18031认证,EN18031报告解读
网络
JhonKI13 小时前
【Linux网络】构建与优化HTTP请求处理 - HttpRequest从理解到实现
linux·网络·http