消息流程
一旦暴露了一个STOMP端点,Spring应用程序就成为连接客户端的STOMP代理。本节描述了服务器端消息的流程。
spring-messaging
模块包含了源自Spring Integration的消息应用程序的基础支持,并且后来被提取并纳入Spring框架以供在许多Spring项目和应用场景中广泛使用。以下列表简要描述了一些可用的消息抽象:
-
Message:消息的简单表示,包括头部和有效载荷。
-
MessageHandler:处理消息的契约。
-
MessageChannel:发送消息的契约,实现生产者和消费者之间的松耦合。
-
SubscribableChannel:带有
MessageHandler
订阅者的MessageChannel
。 -
ExecutorSubscribableChannel:使用
Executor
传递消息的SubscribableChannel
。
Java配置(即@EnableWebSocketMessageBroker
)和XML命名空间配置(即<websocket:message-broker>
)都使用上述组件来组装消息工作流程。以下图表显示了在启用简单内置消息代理时使用的组件:
![message flow simple broker](https://docs.spring.io/spring-framework/reference/_images/message-flow-simple-broker.png)
上述图表显示了三个消息通道:
-
clientInboundChannel
:用于传递从WebSocket客户端接收的消息。 -
clientOutboundChannel
:用于向WebSocket客户端发送服务器消息。 -
brokerChannel
:用于从服务器端应用代码向消息代理发送消息。
下一个图表显示了在配置外部代理(如RabbitMQ)以管理订阅和广播消息时使用的组件:
![message flow broker relay](https://docs.spring.io/spring-framework/reference/_images/message-flow-broker-relay.png)
前两个图表之间的主要区别在于使用“代理中继”将消息传递到外部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
被映射到GreetingController
中的@MessageMapping
方法。 -
从
GreetingController
返回的值被转换为基于返回值的有效载荷和默认目的地标头/topic/greeting
(从输入目的地中使用/app
替换为/topic
)。生成的消息被发送到brokerChannel
并由消息代理处理。 -
消息代理找到所有匹配的订阅者,并通过
clientOutboundChannel
向每个订阅者发送一个MESSAGE帧,从中消息被编码为STOMP帧并发送到WebSocket连接上。
下一节将提供有关注释方法的更多详细信息,包括支持的参数类型和返回值类型。