WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。它可以让服务器主动推送消息到客户端,避免了传统的 HTTP 请求-响应模式的弊端,非常适合实时通讯应用。Spring Boot 提供了非常方便的 WebSocket 支持,下面将介绍如何在 Spring Boot 中使用 WebSocket。
1. 环境搭建
首先,确保你的 Spring Boot 项目已经添加了 WebSocket 相关的依赖。在 pom.xml 中添加以下依赖:
xml
复制编辑
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
该依赖会自动引入 WebSocket 所需的库。
2. 创建 WebSocket 配置类
为了启用 WebSocket,需要在 Spring Boot 中配置 WebSocket。创建一个配置类来启用 WebSocket 支持:
java
复制编辑
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
// 设置消息代理(消息路由路径前缀)
config.enableSimpleBroker("/topic", "/queue"); // 消息推送的目的地前缀
config.setApplicationDestinationPrefixes("/app"); // 客户端发送消息时的路径前缀
}
@Override
public void registerStompEndpoints(org.springframework.web.socket.config.annotation.StompEndpointRegistry registry) {
// 设置 WebSocket 连接的端点
registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS();
}
}
在这个配置类中,我们做了以下几件事:
@EnableWebSocketMessageBroker:启用 WebSocket 消息代理功能。- 配置消息代理
/topic和/queue,这些是服务端推送消息的目标路径。 - 设置 WebSocket 连接的端点
/ws,并启用了SockJS支持,以兼容一些不支持 WebSocket 的浏览器。
3. 创建 WebSocket 控制器
创建一个 WebSocket 控制器,来处理消息的接收和推送。控制器中使用 @MessageMapping 来映射客户端消息,并通过 SimpMessagingTemplate 推送消息给客户端。
java
复制编辑
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;
@Controller
public class WebSocketController {
@MessageMapping("/hello") // 映射客户端发送到 /app/hello 的消息
@SendTo("/topic/greetings") // 向 /topic/greetings 主题发送消息
public String greeting(String message) throws Exception {
return "Hello, " + message + "!";
}
}
在这个控制器中:
@MessageMapping("/hello"):监听客户端发送到/app/hello的消息。@SendTo("/topic/greetings"):将返回的消息推送到/topic/greetings主题。
4. 客户端实现
客户端可以通过 HTML 和 JavaScript 来实现 WebSocket 的连接和消息收发。这里使用 STOMP 协议与 WebSocket 通信,可以通过 SockJS 实现兼容性。
html
复制编辑
<!DOCTYPE html>
<html>
<head>
<title>WebSocket Example</title>
<script src="https://cdn.jsdelivr.net/npm/sockjs-client@1.5.1/dist/sockjs.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/stompjs@2.3.3/dist/stomp.min.js"></script>
</head>
<body>
<div>
<h1>WebSocket Example</h1>
<input type="text" id="name" placeholder="Enter your name"/>
<button onclick="sendMessage()">Send</button>
</div>
<div id="response"></div>
<script type="text/javascript">
var socket = new SockJS('/ws'); // 连接到 Spring Boot 后端的 WebSocket 端点
var stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/greetings', function (response) {
document.getElementById("response").innerText = response.body;
});
});
function sendMessage() {
var name = document.getElementById("name").value;
stompClient.send("/app/hello", {}, name); // 向后端发送消息
}
</script>
</body>
</html>
在客户端实现中,做了以下几件事:
- 使用
SockJS连接到服务器端的 WebSocket 端点/ws。 - 使用
STOMP协议订阅/topic/greetings主题,接收到的消息将显示在页面中。 - 输入框中输入名字后点击按钮,客户端会向服务器发送消息,并展示从服务器接收到的响应。