STOMP(Simple Text Oriented Messaging Protocol)是一种用于在客户端和服务器之间进行实时消息传递的简单文本协议。在Spring框架中,STOMP被用于创建交互式的Web应用程序,通过提供一个基于WebSocket通信的子协议来实现。这使得客户端和服务器之间能够进行异步消息传递,从而实现Web应用程序中的实时更新和通知。
这种方式比起websocket有一个非常好的特点,就是它可以使用几个注解就可以像接口编程一样。同时支持像ws一样全双工的操作方式或者像队列一样,发布订阅。当然也支持集成到队列进行一个交互。这里只是简单写了一个demo,后续进行深度解释其中的源码原理。
服务端
具体代码
package com.example.messagingstompwebsocket;
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.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/queue");
registry.setApplicationDestinationPrefixes("/queue");
//基于内存的STOMP消息代理
// registry.enableSimpleBroker("/queue", "/topic");
//基于RabbitMQ 的STOMP消息代理
/* registry.enableStompBrokerRelay("/queue", "/topic")
.setRelayHost(host)
.setRelayPort(port)
.setClientLogin(userName)
.setClientPasscode(password);*/
// registry.setApplicationDestinationPrefixes("/app", "/foo");
registry.setUserDestinationPrefix("/user");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
// registry.addEndpoint("/gs-guide-websocket").withSockJS();
// registry.addEndpoint("/webSocketServer").setAllowedOrigins("*").withSockJS();
registry.addEndpoint("/webSocketServer")
.withSockJS();
}
}
客户端
<!DOCTYPE html>
<html>
<head>
<title>stomp</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
Welcome<br/><input id="text" type="text" />
<button onclick="send()">发送消息</button>
<button onclick="subscribe2()">订阅消息/topic/sendTest</button>
<button onclick="subscribe1()">订阅消息/topic/subscribeTest</button>
<hr/>
<button onclick="closeWebSocket()">关闭WebSocket连接</button>
<hr/>
<div id="message"></div>
</body>
<script src="http://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script>
<script src="https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js"></script>
<script type="text/javascript">
// 建立连接对象(还未发起连接)
var socket = new SockJS("http://localhost:8080/webSocketServer");
// 获取 STOMP 子协议的客户端对象
var stompClient = Stomp.over(socket);
// 向服务器发起websocket连接并发送CONNECT帧
stompClient.connect(
{},
function connectCallback(frame) {
var userId=1;
// 连接成功时(服务器响应 CONNECTED 帧)的回调方法
setMessageInnerHTML("连接成功");
stompClient.subscribe('/user/' + userId +'/queue/light', function (response) {
setMessageInnerHTML("已成功订阅 "+'/user/' + userId +'/queue/light');
var returnData = JSON.parse(response.body);
setMessageInnerHTML('/user/' + userId +'/queue/light'+" 你接收到的消息为:" + returnData.responseMessage);
});
},
function errorCallBack(error) {
// 连接失败时(服务器响应 ERROR 帧)的回调方法
setMessageInnerHTML("连接失败");
}
);
//发送消息
function send() {
var message = document.getElementById('text').value;
var messageJson = JSON.stringify({ "name": message });
stompClient.send("/app/sendTest", {}, messageJson);
stompClient.send("/app/subscribeTest", {}, messageJson);
// setMessageInnerHTML("/app/sendTest 你发送的消息:" + message);
// stompClient.send("/topic/subscribeTest", {}, messageJson);
setMessageInnerHTML("/topic/subscribeTest 你发送的消息:" + message);
}
//订阅消息
function subscribe1() {
// stompClient.subscribe('/queue/subscribeTest', function (response) {
stompClient.subscribe('/queue/home/monitor/page', function (response) {
// stompClient.subscribe('/ops/home/monitor/page', function (response) {
setMessageInnerHTML("已成功订阅/queue/subscribeTest你接收到的消息为:" + response);
// var returnData = JSON.parse(response.body);
// setMessageInnerHTML("/ops/home/monitor/page 你接收到的消息为:" + response);
});
}
//订阅消息
function subscribe2() {
stompClient.subscribe('/topic/sendTest', function (response) {
setMessageInnerHTML("已成功订阅/topic/sendTest");
// var returnData = JSON.parse(response.body);
setMessageInnerHTML("/topic/sendTest 你接收到的消息为:" + response);
});
}
//将消息显示在网页上
function setMessageInnerHTML(innerHTML) {
document.getElementById('message').innerHTML += innerHTML + '<br/>';
}
</script>
</html>
最后
点赞关注评论一键三连,每周分享技术干货、开源项目、实战经验、国外优质文章翻译等,您的关注将是我的更新动力!