|
对于最新的稳定版本,请使用 Spring Framework 7.0.6! |
消息流
一旦暴露了STOMP端点,Spring应用程序就会成为连接客户端的STOMP代理。本节描述了服务器端的消息流。
The spring-messaging 模块包含最初源自Spring Integration的基础消息传递应用程序支持,并在后来被提取并纳入Spring Framework,以便在许多Spring项目和应用场景中更广泛地使用。
以下列表简要描述了可用的消息传递抽象:
-
消息: 简单表示一条消息,包括头部和有效载荷。
-
消息处理器: 处理消息的契约。
-
消息通道: 用于发送消息的合同,使生产者和消费者之间实现松耦合。
-
可订阅通道:
MessageChannel有MessageHandler订阅者。 -
ExecutorSubscribableChannel:
SubscribableChannel使用一个Executor来传递消息。
Java配置(即,@EnableWebSocketMessageBroker)和XML命名空间配置(即,<websocket:message-broker>)都使用上述组件来组装消息流程。下图显示了启用简单内置消息代理时使用的组件:

前面的图表显示了三个消息通道:
-
clientInboundChannel: 用于传递从WebSocket客户端接收到的消息。 -
clientOutboundChannel: 用于向WebSocket客户端发送服务器消息。 -
brokerChannel: 用于从服务器端应用程序代码中向消息代理发送消息。
下一个图显示了当配置外部代理(如 RabbitMQ)用于管理订阅和广播消息时所使用的组件:

前两个图的主要区别在于使用了“代理中继”来通过 TCP 将消息传递到外部 STOMP 代理,以及将消息从代理传递到已订阅的客户端。
当通过WebSocket连接接收到消息时,这些消息会被解码为STOMP帧,
转换为Spring Message表示形式,并发送到
clientInboundChannel进行进一步处理。例如,目标头以/app开头的STOMP消息
可能会被路由到带注解的控制器中的@MessageMapping方法,而/topic和/queue消息则可能直接
路由到消息代理。
一个处理客户端STOMP消息的注解@Controller可以通过brokerChannel将消息发送到消息代理,代理通过clientOutboundChannel将消息广播给匹配的订阅者。同一个控制器也可以对HTTP请求做出相同的操作,因此客户端可以执行HTTP POST,然后@PostMapping方法可以将消息发送到消息代理以广播给已订阅的客户端。
我们可以通过一个简单的例子来跟踪流程。考虑以下示例,它设置了一个服务器:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/portfolio");
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/app");
registry.enableSimpleBroker("/topic");
}
}
@Controller
public class GreetingController {
@MessageMapping("/greeting")
public String handle(String greeting) {
return "[" + getTimestamp() + ": " + greeting;
}
}
前面的示例支持以下流程:
-
客户端连接到
localhost:8080/portfolio,一旦建立WebSocket连接,STOMP帧就会开始在其上流动。 -
客户端发送一个带有目标头为
/topic/greeting的 SUBSCRIBE 消息。一旦接收到并解码,该消息将被发送到clientInboundChannel,然后被路由到消息代理,该代理存储客户端的订阅。 -
客户端发送一个 SEND 帧到
/app/greeting。/app前缀有助于将其路由到 带注解的控制器。在删除/app前缀后,目标的剩余/greeting部分被映射到@MessageMapping方法中的GreetingController。 -
从
GreetingController返回的值被转换为一个SpringMessage,其负载基于返回值,且默认目标头为/topic/greeting(从输入目标中通过将/app替换为/topic得到)。生成的消息被发送到brokerChannel,并由消息代理处理。 -
消息代理会找到所有匹配的订阅者,并通过
clientOutboundChannel向每个订阅者发送 MESSAGE 帧,从那里消息会被编码为 STOMP 帧并通过 WebSocket 连接发送。
下一节将提供更多有关带注解方法的详细信息,包括支持的参数类型和返回值类型。