WebSocket与gRPC:全双工通信与高效RPC
WebSocket:全双工实时通信 HTTP的局限 HTTP请求-响应模式: 客户端 → 服务器: 请求 客户端 ← 服务器: 响应 问题: - 服务器无法主动推送 - 实时性差(需要轮询) 轮询(Polling): 客户端每隔1秒请求一次: GET /api/messages(1秒后) GET /api/messages(2秒后) GET /api/messages(3秒后) ... 问题:大量无效请求,浪费资源 长轮询(Long Polling): 客户端请求,服务器挂起直到有新消息: GET /api/messages ... 服务器等待30秒 ... ← 返回新消息 问题:仍然是请求-响应模式,连接频繁断开重连 WebSocket协议 核心特点: 全双工通信(双向同时传输) 基于TCP 低开销(头部仅2字节) 持久连接 协议升级: # 客户端发起升级请求 GET /chat HTTP/1.1 Host: example.com 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= # 升级完成,使用WebSocket通信 Spring Boot WebSocket 服务端 // WebSocket配置 @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(chatHandler(), "/chat") .setAllowedOrigins("*"); // CORS } @Bean public ChatHandler chatHandler() { return new ChatHandler(); } } // WebSocket处理器 @Component public class ChatHandler extends TextWebSocketHandler { private static final Set<WebSocketSession> sessions = new CopyOnWriteArraySet<>(); @Override public void afterConnectionEstablished(WebSocketSession session) { sessions.add(session); System.out.println("新连接:" + session.getId()); } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { String payload = message.getPayload(); System.out.println("收到消息:" + payload); // 广播给所有客户端 for (WebSocketSession s : sessions) { if (s.isOpen()) { s.sendMessage(new TextMessage("服务器转发:" + payload)); } } } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) { sessions.remove(session); System.out.println("连接关闭:" + session.getId()); } } 客户端(JavaScript) // 建立WebSocket连接 const ws = new WebSocket('ws://localhost:8080/chat'); // 连接打开 ws.onopen = () => { console.log('WebSocket连接已建立'); ws.send('你好,服务器'); }; // 接收消息 ws.onmessage = (event) => { console.log('收到消息:', event.data); }; // 连接关闭 ws.onclose = () => { console.log('WebSocket连接已关闭'); }; // 连接错误 ws.onerror = (error) => { console.error('WebSocket错误:', error); }; STOMP:WebSocket消息协议 问题 原始WebSocket只传输文本/二进制: ...