【stomp 实战】Spring websocket使用详解和基本原理

spring框架对websocket有很好的支持,stomp协议作为websocket的子协议,Spring也做了很多封装,让我们在开发中易于使用。

学习使用Spring的Websocket模块,当然最好的办法就是看官网说明了。本篇文章对官网做一些简述和个人的理解。

开始使用

依赖引入

第一步当然是引入SpringBoot的包了

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

这个包实际上引入了两个依赖spring-messaging 和 spring-websocket

如何开启stomp的支持

java 复制代码
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

	@Override
	public void registerStompEndpoints(StompEndpointRegistry registry) {
		registry.addEndpoint("/portfolio"); 
	}

	@Override
	public void configureMessageBroker(MessageBrokerRegistry config) {
		config.setApplicationDestinationPrefixes("/app"); 
		config.enableSimpleBroker("/topic", "/queue"); 
	}
}
  • registry.addEndpoint("/portfolio"); 添加一个后端,前端可以通过这个端点,进行websocket通信
    对应的前端代码可以这么写
javascript 复制代码
 var socket = new SockJS('/portfolio');
 stompClient = Stomp.over(socket);
  • config.setApplicationDestinationPrefixes("/app"); 这个是前端可以往这个路径发送消息。
    前端代码这么写的:
javascript 复制代码
 stompClient.send("/app/echo", {}, JSON.stringify(msg));

后端可以定义一个controller,来接收这个消息,所以这个/app的意思可以理解为所有@MessageMapping的前缀。

java 复制代码
@Controller
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class StompController {
    @MessageMapping("/echo")
    public void echo(Principal principal, Msg msg) {
    //代码略
    }
}
  • config.enableSimpleBroker("/topic", "/queue"); 这个是启用消息broker。广播消息的前缀。当我们需要发送广播消息给客户端时,需要满足这个前缀条件。
    前端这么订阅消息,是topic前缀
javascript 复制代码
 //订阅广播消息topic
 stompClient.subscribe("/topic/boardCast/hello", function (response) {
 });

后端代码通过消息broker,可以将此消息发送给订阅了"/topic/boardCast/hello"的客户端。

java 复制代码
public class StompController {
    private final SimpMessageSendingOperations msgOperations;
    public void test(message) {
        msgOperations.send("/topic/boardCast/hello",message);

    }
}

消息的流转过程

首先得理解以下几个概念

  • Message: 消息,包括消息头和消息体.
  • MessageHandler: 处理消息的处理器
  • MessageChannel:消息通道,客户端发送消息,到达服务器(inboundChannel)。服务器通过通道(outboundChannel)发送消息给客户端
  • MessageBroker:消息分发的处理器,消息怎么流转,是由broker分发的

代码示例

前端往/app/echo发送了一条消息

javascript 复制代码
    //主动发送消息给服务器,对应的后端topic为/app/echo2
    function send() {
        var value = document.getElementById("content").value;
        var msg = {
            msgType: 1,
            content: value
        };
        stompClient.send("/app/echo2", {}, JSON.stringify(msg));
    }

后端代码得注册/app前缀

java 复制代码
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
	@Override
	public void configureMessageBroker(MessageBrokerRegistry config) {
		config.setApplicationDestinationPrefixes("/app"); 
		config.enableSimpleBroker("/topic", "/queue"); 
	}
}

然后定义一个Controller来接收用户消息, @MessageMapping("/echo"),这里就是子路径了,拼起来正好是/app/echo,这时Wesocket请求会到达echo方法。

java 复制代码
@Controller
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class StompController {
    private final SimpMessageSendingOperations msgOperations;
    @MessageMapping("/echo2")
    public void echo2() {
        msgOperations.convertAndSend("/topic/boardCast/hello", "hello boardCast Message");
    }
}

上面示例代码的执行流程,消息的流转如下图所示

  • 消息通过inboundChannel到服务器
  • 此时根据消息的前缀,会匹配出/app开头的,是需要找SimpAnnotationMethodMessageHandler。这个处理器,是找Controller来执行
  • Controller中收到该消息,其方法中调用了一个发送方法。发往/topic/boardCast/hello
  • 此时也会根据消息的前缀,找到消息处理器,SimpleBrokerMessageHandler
  • SimpleBrokerMessageHandler遍历用户会话,找到订阅了/topic/boardCast/hello的用户。通过outboundChannel将消息发送出去

以上就是用户发送一个消息,服务端接收。服务端同时再发送一条广播消息给对应的客户端的过程。

总结

通过本节内容,我们学到了以下内容

  • 几个配置的含义
    • registry.addEndpoint("/portfolio"); 配置WebSocket端点
    • config.setApplicationDestinationPrefixes("/app"); 配置Controller的目的前缀。这是用于服务端接收客户端消息的前缀
    • config.enableSimpleBroker("/topic", "/queue"); 配置用户可以订阅的destination。服务端通过msgOperations.convertAndSend("/topic/boardCast/hello", "hello boardCast Message");可以发送消息给订阅了此destination的用户
  • 消息的流转过程,大家可以根据上面的流程图,阅读一下源码

本节的示例源码,都在开源项目中:文章链接【stomp实战】搭建一套websocket推送平台。文章最后有项目地址。

相关推荐
网络安全天地23 分钟前
使用 Flutter 制作地图应用
websocket·网络协议·tcp/ip·http·网络安全·https·udp
to future_38 分钟前
非阻塞IO,fcntl,多路转接,select,poll,epoll,reactor
linux·网络协议
车载测试工程师42 分钟前
ARXML文件解析-1
经验分享·网络协议·tcp/ip·车载系统
JavaEdge.2 小时前
ssl.SSLCertVerificationError报错解决方案
网络·网络协议·ssl
派小汤2 小时前
Springboot + Vue + WebSocket + Notification实现消息推送功能
vue.js·spring boot·websocket
JhonKI2 小时前
【从零实现Json-Rpc框架】- 项目实现 - 客户端注册主题整合 及 rpc流程示意
c++·qt·网络协议·rpc·json
LUCIAZZZ4 小时前
计算机网络-TCP的拥塞控制
网络协议·tcp/ip·计算机网络
圈圈编码6 小时前
WebSocket
java·网络·spring boot·websocket·网络协议·spring
苏格拉没有底_coder7 小时前
【Easylive】视频在线人数统计系统实现详解 & WebSocket 及其在在线人数统计中的应用
websocket·网络协议
吴盐煮_7 小时前
如何判断一条连接是TCP连接还是UDP连接?
网络协议·tcp/ip·udp