跳到主要内容

WebSocket 与长连接

问题

WebSocket 和 HTTP 有什么区别?什么时候用 WebSocket?

答案

WebSocket vs HTTP

维度HTTPWebSocket
通信方向请求-响应(单向)全双工(双向)
连接短连接(Keep-Alive 复用)长连接
协议http:// / https://ws:// / wss://
数据格式文本(有 Header 开销)帧(开销小)
服务端推送不支持(需轮询)原生支持

WebSocket 握手过程

WebSocket 基于 HTTP 升级协议建立连接。

// 客户端请求升级
GET /chat HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

// 服务端同意升级
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

握手完成后,TCP 连接保持,双方可以随时互发数据。

实时通信方案对比

方案原理延迟适用场景
短轮询客户端定时请求高(轮询间隔)简单场景
长轮询服务端 hold 住请求,有数据再返回中等兼容性要求高
SSE服务端单向推送单向通知、日志流
WebSocket全双工最低IM、实时协作、游戏

Java WebSocket(Spring)

Spring WebSocket 服务端
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(chatHandler(), "/ws/chat")
.setAllowedOrigins("*");
}

@Bean
public WebSocketHandler chatHandler() {
return new ChatWebSocketHandler();
}
}

public class ChatWebSocketHandler extends TextWebSocketHandler {
// 保存所有在线连接
private final Set<WebSocketSession> sessions = ConcurrentHashMap.newKeySet();

@Override
public void afterConnectionEstablished(WebSocketSession session) {
sessions.add(session);
}

@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message)
throws Exception {
// 广播消息给所有在线用户
for (WebSocketSession s : sessions) {
if (s.isOpen()) {
s.sendMessage(message);
}
}
}

@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
sessions.remove(session);
}
}

常见面试问题

Q1: WebSocket 如何保持连接不断开?

答案

通过心跳机制:客户端或服务端定时发送 Ping 帧,对方回复 Pong 帧。如果超过一定时间没收到 Pong,认为连接断开,触发重连。

Q2: WebSocket 集群部署怎么处理?

答案

WebSocket 是长连接,用户连接到某台服务器后,消息只在该服务器内可见。集群需要:

  1. 消息广播:通过 Redis Pub/Sub 或 MQ,一台服务器收到消息后广播给所有节点
  2. Session 共享:用 Redis 记录用户连接在哪台服务器
  3. Sticky Session:负载均衡器按用户 ID 路由到固定服务器

Q3: SSE 和 WebSocket 怎么选?

答案

  • SSE:只需要服务端向客户端推送(如通知、日志流、AI 回答流式输出),基于 HTTP 天然支持重连
  • WebSocket:需要双向通信(如 IM 聊天、实时协作),开销更小

相关链接