当前位置: 首页 > news >正文

Web Socket 学习笔记

1. 什么是 WebSocket?它与 HTTP 有什么区别?

WebSocket 是一种基于 TCP 的全双工通信协议,它通过 HTTP/1.1 的 Upgrade 机制建立连接,建立后切换为 WebSocket 协议。虽然 HTTP/2 和 HTTP/3 在协议层更先进,但它们并不直接兼容标准 WebSocket。目前主流浏览器仍使用 HTTP/1.1 来发起 WebSocket 握手。

与 HTTP 的主要区别:HTTP 是单向,请求-响应,短连接/每次请求重连,头部大,每次都带 Header,实时性 差,需要轮询,而 WebSocket 是双向,任意一方主动发消息,长连接,连接建立后持续有效,头部小,建立连接后几乎无额外开销,实时性极好,消息即发即达。

2. WebSocket 协议是如何建立连接的?描述握手过程。

WebSocket 是基于 HTTP/1.1 的 Upgrade 机制发起连接请求,握手成功后,通信协议从 HTTP 升级为 WebSocket,建立一个持久、全双工的 TCP 通道。

WebSocket 的建立连接过程基于 HTTP/1.1 的 Upgrade 机制。客户端首先发起一个带有 Upgrade: websocket 和 Sec-WebSocket-Key 的 GET 请求,服务端验证后返回 101 状态码和 Sec-WebSocket-Accept 响应头表示协议切换成功。此后双方进入 WebSocket 协议层,通过帧格式进行双向通信,连接保持不断开,实现低延迟实时消息推送。

3. 如何给指定用户推送消息?如何广播

1. 给指定用户推送消息

    • 服务器端需要维护一个用户标识(如 userId)和 WebSocket 会话(Session)的映射关系,一般使用线程安全的集合保存,如 ConcurrentHashMap<String, Session>
    • 当用户连接建立时,将用户的 ID 和对应的 Session 绑定。
    • 推送消息时,通过用户 ID 找到对应 Session,调用发送接口推送消息。
    • 在 Spring 框架中,可以通过 SimpMessagingTemplate.convertAndSendToUser() 方法给指定用户发送消息,客户端订阅 /user/{userId}/queue/... 主题。

2. 广播消息

    • 广播是向所有在线连接的 Session 发送相同消息。
    • 服务器维护一个包含所有在线 Session 的集合(如 CopyOnWriteArraySet<Session>)。
    • 遍历所有 Session 调用发送接口,将消息广播给每个连接。
    • 在 Spring 中,可以通过 SimpMessagingTemplate.convertAndSend() 发送到公共的广播主题,比如 /topic/broadcast

4. WebSocket 如何保证通信安全?如何做身份校验?如何防止非法连接?

WebSocket 保障通信安全主要通过使用 WSS,即基于 TLS 的加密连接,防止数据在传输过程中被窃听或篡改。身份校验可以在握手阶段通过 Token 或 Cookie 验证客户端合法性,连接建立后还可以通过消息校验身份。防止非法连接手段包括校验 Origin,限制连接频率,白名单策略,以及消息格式校验。此外,应用层还可以对消息进行加密和签名,确保数据完整性和真实性。

5. 如何处理 WebSocket 连接断开和重连?

WebSocket 连接断开时,客户端通过监听 onclose 和 onerror 事件检测。实现自动重连机制,采用指数退避策略避免频繁重连。使用心跳机制定时发送 Ping 消息,确保连接活跃并及时发现断线。断线重连后,客户端重新认证并同步断线期间的消息,保证业务连续性。服务端也通过心跳检测及时关闭无效连接,保障资源合理使用。

6. WebSocket 相对于 HTTP 轮询和长轮询有什么优势?

WebSocket 通过建立持久的双向 TCP 连接,实现客户端和服务器之间全双工通信,避免了 HTTP 轮询和长轮询不断建立连接的开销,极大降低了延迟和带宽消耗。相比轮询的固定请求间隔和长轮询的请求响应周期,WebSocket 能即时推送消息,更适合实时性要求高的应用场景,如在线聊天和实时游戏。

7. WebSocket 如何实现心跳机制来保持连接?

WebSocket 实现心跳机制常用两种方式:一种是使用协议内置的 ping/pong 控制帧,由服务端定期发送 ping 检测连接;另一种是在客户端用自定义 JSON 消息发送“ping”,服务端回应“pong”,双向确认连接活跃。若一定时间内未收到心跳响应,可认为连接断开并进行清理或重连,确保资源不被假连接占用。

8. WebSocket 如何在分布式部署下共享状态?

在分布式部署下,WebSocket 无法通过本地内存感知全局连接状态。我们通常使用 Redis 等组件记录用户和节点的映射关系(如 userId → serverId),推送消息时先查找用户所在节点,然后通过 HTTP 或消息中间件转发到对应节点,由该节点的本地连接完成消息推送。广播消息则通过消息队列广播给所有节点,节点再向自身的连接用户推送,实现全局一致的消息投递。

9. WebSocket 在哪些场景下适合使用?哪些场景不适合?

WebSocket 适合对实时性要求高的场景,比如在线聊天、实时通知、游戏、协作编辑等,能实现低延迟的双向通信。而像信息展示、周期性查询、用户访问不频繁等低实时性场景,不适合用 WebSocket,HTTP 接口或轮询反而更简单可靠。此外,面对大规模低频连接的场景,MQTT 等更轻量的协议更合适。

10. Spring Boot 中如何实现 WebSocket?

1. 添加依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

2. 配置类

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {@Overridepublic void registerStompEndpoints(StompEndpointRegistry registry) {registry.addEndpoint("/ws-stomp").setAllowedOrigins("*").withSockJS(); // 客户端连接入口}@Overridepublic void configureMessageBroker(MessageBrokerRegistry registry) {registry.enableSimpleBroker("/topic", "/queue"); // 推送端点(服务器推送用)registry.setApplicationDestinationPrefixes("/app"); // 客户端发送消息前缀}
}

3. 控制器接收消息

@Controller
public class MessageController {@MessageMapping("/chat/send") // 客户端发到 /app/chat/send@SendTo("/topic/chat")        // 广播到所有订阅者public String sendMessage(String message) {return message;}
}

4. 推送给指定用户(点对点)

@Autowired
private SimpMessagingTemplate messagingTemplate;public void sendToUser(String userId, String msg) {messagingTemplate.convertAndSendToUser(userId, "/queue/notify", msg);
}

客户端订阅:/user/queue/notify

http://www.dtcms.com/a/278884.html

相关文章:

  • C# 入门学习教程(三)
  • Python基础语法1:注释与输入输出、变量与简单数据类型、运算符与表达式、条件判断与循环
  • 云原生技术与应用-Containerd容器技术详解
  • MySQL数据库的基础操作
  • AI驱动的软件工程(下):AI辅助的质检与交付
  • nvidia-smi命令参数解释
  • 机器学习(ML)、深度学习(DL)、强化学习(RL):人工智能的三驾马车
  • 外星人电脑Alienware Aurora R11原装出厂OEM预装Windows10系统
  • 自动驾驶数据仓库:时间片合并算法。
  • 【React Native】ScrollView 和 FlatList 组件
  • 基于ASP.NET+SQL Server实现(Web)排球赛事网站
  • Java文件操作
  • PTKQuery
  • 大规模测试自动化测试指南
  • day9 串口通信
  • 如何单独安装设置包域名
  • Kafka Broker源码解析(上篇):存储引擎与网络层设计
  • Java HTTP应用开发:从基础到实战
  • C语言-流程控制
  • 使⽤Pytorch构建⼀个神经⽹络
  • Linux 消息队列接收与处理线程实现
  • 【HTTP版本演变】
  • 考完数通,能转云计算/安全方向吗?转型路径与拓展路线分析
  • Elasticsearch9.x核心架构概述
  • Redis7持久化
  • 【postgresql数据库实现表的树结构查询】
  • 项目进度中间节点缺失,如何精细化分解任务
  • MIPI DSI(三) MIPI DSI 物理层和 D-PHY
  • 《大数据技术原理与应用》实验报告三 熟悉HBase常用操作
  • 现代数据平台能力地图:如何构建未来数据平台的核心能力体系