此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Framework 6.2.10! |
消息流
一旦 STOMP 端点被公开,Spring 应用程序就会成为 连接的客户端。本节介绍服务器端的消息流。
这spring-messaging
模块包含对消息传递应用程序的基础支持
起源于 Spring Integration,是
后来被提取并合并到 Spring 框架中,以便在许多 Spring 项目和应用场景中更广泛地使用。
以下列表简要介绍了一些可用的消息传递抽象:
-
留言: 消息的简单表示形式,包括标头和有效负载。
-
MessageHandler 的 MessageHandler 中: 用于处理消息的协定。
-
消息通道: 用于发送消息的合约,使生产者和使用者之间能够松散耦合。
-
SubscribableChannel:
MessageChannel
跟MessageHandler
用户。 -
ExecutorSubscribableChannel:
SubscribableChannel
使用Executor
用于传递消息。
Java 配置(即@EnableWebSocketMessageBroker
) 和 XML 命名空间配置
(即,<websocket:message-broker>
) 使用上述组件来组合消息
工作流程。下图显示了当简单内置消息时使用的组件
broker 已启用:

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

前面两个图之间的主要区别在于使用“代理中继”进行传递 消息通过 TCP 发送到外部 STOMP 代理,并从 经纪人到订阅的客户。
当从 WebSocket 连接接收消息时,它们会被解码为 STOMP 帧,
变成了一根SpringMessage
表示,并发送到clientInboundChannel
用于进一步处理。例如,其 STOMP 消息
目标标头以/app
可以路由到@MessageMapping
方法
带注释的控制器,而/topic
和/queue
消息可以直接路由
到消息代理。
一个带注释的@Controller
处理来自客户端的 STOMP 消息的 可以将消息发送到
消息代理通过brokerChannel
,并且代理广播
通过clientOutboundChannel
.一样
控制器也可以执行相同的作来响应 HTTP 请求,因此客户端可以执行
HTTP POST,然后是@PostMapping
方法可以向消息代理发送消息
广播到订阅的客户端。
我们可以通过一个简单的例子来追踪流程。请考虑以下设置服务器的示例:
-
Java
-
Kotlin
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/portfolio");
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/app");
registry.enableSimpleBroker("/topic");
}
}
@Configuration
@EnableWebSocketMessageBroker
class WebSocketConfiguration : WebSocketMessageBrokerConfigurer {
override fun registerStompEndpoints(registry: StompEndpointRegistry) {
registry.addEndpoint("/portfolio")
}
override fun configureMessageBroker(registry: MessageBrokerRegistry) {
registry.setApplicationDestinationPrefixes("/app")
registry.enableSimpleBroker("/topic")
}
}
-
Java
-
Kotlin
@Controller
public class GreetingController {
@MessageMapping("/greeting")
public String handle(String greeting) {
return "[" + getTimestamp() + ": " + greeting;
}
private String getTimestamp() {
return new SimpleDateFormat("MM/dd/yyyy h:mm:ss a").format(new Date());
}
}
@Controller
class GreetingController {
@MessageMapping("/greeting")
fun handle(greeting: String): String {
return "[${getTimestamp()}: $greeting"
}
private fun getTimestamp(): String {
return SimpleDateFormat("MM/dd/yyyy h:mm:ss a").format(Date())
}
}
前面的示例支持以:
-
客户端连接到
localhost:8080/portfolio
并且,一次是 WebSocket 连接 建立后,STOMP 帧开始在其上流动。 -
客户端发送目标标头为
/topic/greeting
.收到后 并解码后,消息将发送到clientInboundChannel
然后路由到 消息代理,用于存储客户端订阅。 -
客户端将 SEND 帧发送到
/app/greeting
.这/app
前缀有助于将其路由到 带注释的控制器。之后/app
前缀被剥离,其余的/greeting
目标的一部分映射到@MessageMapping
方法GreetingController
. -
从
GreetingController
变成了弹簧Message
跟 基于返回值的有效负载和默认目标标头/topic/greeting
(派生自输入目标,其中/app
替换为/topic
).生成的消息被发送到brokerChannel
并处理 由消息代理。 -
消息代理查找所有匹配的订阅者,并向每个订阅者发送一个 MESSAGE 帧 通过
clientOutboundChannel
,消息从中编码为 STOMP 帧 并在 WebSocket 连接上发送。
下一节提供了有关注释方法的更多详细信息,包括 支持的参数和返回值类型。