下面将对“SpringBoot集成WebSocket进行点对点和广播实时推送”的完整攻略进行详细讲解,建议您认真阅读。
- 概述
WebSocket是HTML5推出的一种新型协议,它类似于HTTP协议,但对服务器尤其友好。它允许服务器在任何时刻向客户端推送数据,而不必等待客户端去请求。相对于传统的Ajax轮询方式,WebSocket更加高效、实时。
SpringBoot是基于Spring Framework的一个快速开发框架,它把Spring全家桶集成在一起,使得使用Spring开发Web应用变得更加便捷。
在本教程中,我们将讲解如何使用SpringBoot集成WebSocket进行点对点和广播实时推送。
- 环境准备
在开始之前,我们需要准备好以下环境:
- JDK 1.8或以上
- Maven
-
IntelliJ IDEA或Eclipse
-
创建SpringBoot项目
首先,我们需要创建一个SpringBoot项目。打开IntelliJ IDEA,选择“Create New Project”,然后选择“Spring Initializr”。
在弹出的窗口中,填写项目的基本信息,如下图所示:
点击“Next”按钮,然后选择要导入的依赖。在本教程中,我们需要选择“WebSocket”和“Thymeleaf”依赖,如下图所示:
点击“Next”和“Finish”按钮,完成项目的创建。
- 添加WebSocket配置
在项目中添加WebSocket,需要添加@EnableWebSocket注解,并实现WebSocketConfigurer接口,如下所示:
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new MyHandler(), "/myHandler").setAllowedOrigins("*");
}
private class MyHandler extends TextWebSocketHandler {
@Override
public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
session.sendMessage(new TextMessage("Hello, " + message.getPayload() + "!"));
}
}
}
在上述代码中,我们创建了一个WebSocket处理程序MyHandler,并将这个处理程序映射到了“/myHandler”路径下。在MyHandler中,我们重写了handleTextMessage方法,在该方法中向客户端发送了一条问候消息。
另外,我们还需要添加一个WebSocket消息代理控制器,它可以把WebSocket消息转发到STOMP消息代理上,代码如下:
@Configuration
public class WebSocketMessageBrokerConfigurer implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/topic");
registry.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/stomp").setAllowedOrigins("*").withSockJS();
}
}
在上述代码中,我们调用registry.enableSimpleBroker("/topic")方法以启用简单的消息代理,并将消息代理目的地设置为“/topic”。我们还调用registry.setApplicationDestinationPrefixes("/app")方法以设置应用程序目的地前缀为“/app”。
另外,我们也注册了一个STOMP端点“/stomp”,并调用withSockJS()方法以启用SockJS。
- 添加页面代码
在本教程中,我们将使用Thymeleaf作为页面模板引擎,因此我们需要在项目中添加一个index.html文件,并添加WebSocket客户端代码。
在src/main/resources/templates目录下创建index.html文件,代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>WebSocket Demo</title>
</head>
<body>
<h1>WebSocket Demo</h1>
<input type="text" id="name" placeholder="请输入你的名字"><br/><br/>
<input type="button" value="发送" onclick="sendMessage()"><br/><br/>
<p id="message"></p>
<script src="https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js"></script>
<script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script>
<script>
var stompClient = null;
function connect() {
var socket = new SockJS('/stomp');
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/greetings', function (message) {
showMessage(JSON.parse(message.body).content);
});
});
}
function disconnect() {
if (stompClient != null) {
stompClient.disconnect();
}
console.log("Disconnected");
}
function sendMessage() {
var name = document.getElementById('name').value;
stompClient.send("/app/hello", {}, JSON.stringify({'name': name}));
}
function showMessage(message) {
document.getElementById('message').innerHTML = message;
}
connect();
</script>
</body>
</html>
在上述代码中,我们使用了SockJS和STOMP.js库来简化WebSocket的使用。在页面打开时,我们调用connect()函数以连接WebSocket。在connect()函数中,我们创建了一个WebSocket连接,并订阅了“/topic/greetings”路径下的消息。在sendMessage()函数中,我们发送了一条消息到“/app/hello”路径下,消息体为一个json字符串。在showMessage()函数中,我们更新了页面上显示的消息。
- 示例一:点对点实时推送
在这个示例中,我们将展示如何使用点对点实时推送。为了模拟多个客户端,我们可以同时打开多个浏览器窗口,每个窗口都使用相同的WebSocket连接。
首先,我们需要修改WebSocket处理程序,使其可以接收客户端发送的消息,并将其转发给指定的客户端:
private static Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>();
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
sessions.put(session.getId(), session);
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
sessions.remove(session.getId());
}
@Override
public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
String[] parts = message.getPayload().split(" ");
String sessionId = parts[0];
String content = parts[1];
if (sessions.containsKey(sessionId)) {
sessions.get(sessionId).sendMessage(new TextMessage(content));
}
}
在上述代码中,我们使用一个ConcurrentHashMap来存储所有WebSocket会话。我们在afterConnectionEstablished()方法中保存每个会话,然后在afterConnectionClosed()方法中删除它。在handleTextMessage()方法中,我们首先解析从客户端发送过来的消息,得到sessionId和content两个部分,然后在sessions中查找对应的WebSocket会话,完成消息的转发。
接下来,我们需要修改前端客户端代码,以便客户端能够向指定的客户端发送消息:
function sendMessage() {
var sessionId = document.getElementById('sessionId').value;
var content = document.getElementById('content').value;
stompClient.send("/app/message/" + sessionId, {}, sessionId + ' ' + content);
}
在上述代码中,我们使用sessionId来标识指定的WebSocket会话,然后通过“/app/message/${sessionId}”路径发送消息。
最后,我们需要修改页面代码,添加用于输入sessionId和content的文本框,并添加发送按钮,代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>WebSocket Demo</title>
</head>
<body>
<h1>WebSocket Demo</h1>
<label>SessionId:</label><input type="text" id="sessionId" placeholder="请输入接收方WebSocket的SessionId"><br/><br/>
<label>Content:</label><input type="text" id="content" placeholder="请输入要发送的内容"><br/><br/>
<input type="button" value="发送" onclick="sendMessage()"><br/><br/>
<p id="message"></p>
<script src="https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js"></script>
<script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script>
<script>
var stompClient = null;
function connect() {
var socket = new SockJS('/stomp');
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
console.log('Connected: ' + frame);
stompClient.subscribe('/user/queue/messages', function (message) {
showMessage(JSON.parse(message.body).content);
});
});
}
function disconnect() {
if (stompClient != null) {
stompClient.disconnect();
}
console.log("Disconnected");
}
function sendMessage() {
var sessionId = document.getElementById('sessionId').value;
var content = document.getElementById('content').value;
stompClient.send("/app/message/" + sessionId, {}, sessionId + ' ' + content);
}
function showMessage(message) {
document.getElementById('message').innerHTML = message;
}
connect();
</script>
</body>
</html>
重启应用程序,打开多个浏览器窗口,并分别输入不同的sessionId和content,点击发送按钮,可以看到接收方的WebSocket会话可以实时接收到消息。
- 示例二:广播实时推送
在这个示例中,我们将展示如何使用广播实时推送。在这个示例中,我们将使用SpringBoot内置的简单消息代理实现广播功能。
首先,我们需要修改WebSocket处理程序,使其可以发布新的消息到消息代理上:
@MessageMapping("/hello")
@SendTo("/topic/greetings")
public String hello(@Payload String name) {
return "Hello, " + name + "!";
}
在上述代码中,我们使用@MessageMapping("/hello")注解来监听“/app/hello”路径下的消息,并使用@SendTo("/topic/greetings")注解来将消息转发到消息代理上。
接下来,我们需要修改前端客户端代码,以便可以自动接收来自“/topic/greetings”路径下的新消息。修改代码如下:
function connect() {
var socket = new SockJS('/stomp');
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/greetings', function (message) {
showMessage(JSON.parse(message.body));
});
});
}
在上述代码中,我们使用stompClient.subscribe('/topic/greetings')方法来监听“/topic/greetings”路径下的新消息,并将其展示在页面上。
重启应用程序,打开多个浏览器窗口,并输入不同的name,点击发送按钮,可以看到所有窗口都可以接收到广播消息。
到这里,我们就成功地完成了使用SpringBoot集成WebSocket进行点对点和广播实时推送的教程。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot集成WebSocket【基于纯H5】进行点对点[一对一]和广播[一对多]实时推送 - Python技术站