一、WebSocket 在 Java 生态中的发展历程
阶段 1:原生 WebSocket(2011-2013)
背景:WebSocket 协议(RFC 6455)标准化后,Java 通过 JSR-356(Java WebSocket API)提供官方支持。
特点:需手动管理连接生命周期,代码复杂度高。
前后端示例:
- 后端(JSR-356) :
typescript
@ServerEndpoint("/ws")
public class WebSocketEndpoint {
private static final Set<Session> sessions = Collections.synchronizedSet(new HashSet<>());
@OnOpen
public void onOpen(Session session) {
sessions.add(session);
}
@OnMessage
public void onMessage(String message, Session session) {
// 手动广播消息给所有客户端
sessions.forEach(s -> {
try {
s.getBasicRemote().sendText("广播:" + message);
} catch (IOException e) {
e.printStackTrace();
}
});
}
}
- 前端(原生 JS) :
ini
const ws = new WebSocket('ws://localhost:8080/ws');
ws.onmessage = (event) => console.log(event.data);
ws.send('Hello');
阶段 2:Spring WebSocket(2013-2015)
背景:Spring 4.0 引入spring-websocket模块,简化开发并支持 SockJS 降级。
特点:抽象了底层 API,通过WebSocketHandler处理消息。
前后端示例:
- 后端(Spring WebSocket) :
typescript
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(myHandler(), "/ws").withSockJS();
}
@Bean
public WebSocketHandler myHandler() {
return new TextWebSocketHandler() {
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) {
session.sendMessage(new TextMessage("Echo: " + message.getPayload()));
}
};
}
}
- 前端(SockJS) :
ini
const sock = new SockJS('http://localhost:8080/ws');
sock.onmessage = (e) => console.log(e.data);
sock.send('Hello Spring');
阶段 3:STOMP over WebSocket + SimpMessagingTemplate(2015-2017)
背景:Spring 4.1 引入 STOMP(简单文本导向消息协议)支持,通过SimpMessagingTemplate简化消息广播。
特点:
- 基于消息代理(如 RabbitMQ、ActiveMQ)实现发布 - 订阅模式
- 引入消息目的地(如/topic、/queue)和消息代理
- 使用@MessageMapping注解处理消息
核心组件:
- SimpMessagingTemplate:用于向客户端发送消息
- @EnableWebSocketMessageBroker:启用消息代理
前后端示例:
- 后端(Spring STOMP) :
typescript
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic"); // 启用内存代理,处理/topic前缀的目的地
config.setApplicationDestinationPrefixes("/app"); // 处理/app前缀的客户端消息
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws").withSockJS();
}
}
@Controller
public class GreetingController {
@Autowired
private SimpMessagingTemplate messagingTemplate;
@MessageMapping("/hello") // 处理客户端发送到/app/hello的消息
public void handleMessage(String message) {
messagingTemplate.convertAndSend("/topic/greetings", "广播:" + message);
}
}
- 前端(STOMP.js) :
javascript
const socket = new SockJS('http://localhost:8080/ws');
const stompClient = Stomp.over(socket);
stompClient.connect({}, () => {
// 订阅/topic/greetings目的地的消息
stompClient.subscribe('/topic/greetings', (message) => {
console.log(message.body);
});
// 发送消息到/app/hello
stompClient.send('/app/hello', {}, 'Hello STOMP');
});
阶段 4:Spring Boot Auto-Configuration(2017 至今)
背景:Spring Boot 2.x 进一步简化配置,自动装配 WebSocket 和 STOMP。
特点:
- 依赖spring-boot-starter-websocket自动配置
- 通过application.properties定制参数
前后端示例:
- 后端(Spring Boot + STOMP) :
less
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
// 配置与阶段3相同
}
@Controller
public class ChatController {
@MessageMapping("/chat")
public void handleChatMessage(@Payload ChatMessage message) {
messagingTemplate.convertAndSend("/topic/messages", message);
}
}
// 消息模型
@Data
public class ChatMessage {
private String sender;
private String content;
}
- 前端(Vue.js + STOMP.js) :
xml
<script>
export default {
data() {
return {
stompClient: null,
messages: []
};
},
mounted() {
this.connect();
},
methods: {
connect() {
const socket = new SockJS('http://localhost:8080/ws');
this.stompClient = Stomp.over(socket);
this.stompClient.connect({}, () => {
this.stompClient.subscribe('/topic/messages', (message) => {
this.messages.push(JSON.parse(message.body));
});
});
},
sendMessage() {
this.stompClient.send('/app/chat', {}, JSON.stringify({
sender: 'user',
content: 'Hello from Vue'
}));
}
}
}
</script>
二、SimpMessagingTemplate 的原理与优势
原理:
SimpMessagingTemplate是 Spring 提供的消息发送工具,封装了 WebSocket 消息的底层细节:
- 消息路由:根据目的地(如/topic/xxx)将消息路由到对应代理
- 消息转换:自动将对象序列化为 JSON(默认)
- 代理支持:支持内存代理(SimpleBroker)或外部代理(RabbitMQ、ActiveMQ)
优势:
- 解耦发送者与接收者:通过目的地隔离,发送者无需知道接收者是谁
- 简化广播:直接向/topic发送消息,自动推送给所有订阅者
- 事务支持:与 Spring 事务集成,确保消息原子性
三、总结
阶段 | 核心技术 | 消息模型 | 典型场景 |
---|---|---|---|
原生 WebSocket | JSR-356 | 手动管理连接 | 简单点对点通信 |
Spring WebSocket | WebSocketHandler | 请求 - 响应 | 简单消息处理 |
STOMP + SimpTemplate | STOMP 协议 + 消息代理 | 发布 - 订阅 | 群聊、实时通知 |
Spring Boot | 自动配置 + STOMP | 注解驱动 | 微服务实时通信 |
演进逻辑:从底层 API 到高层抽象,从手动管理到自动配置,逐步降低开发门槛并提升扩展性。