Interception

Events为 STOMP 连接的生命周期提供通知,但不针对每条客户端消息。应用程序也可以注册 `ChannelInterceptor`以拦截任何消息,并且在处理链的任何部分进行拦截。以下示例展示如何拦截来自客户端的入站消息:

Events provide notifications for the lifecycle of a STOMP connection but not for every client message. Applications can also register a ChannelInterceptor to intercept any message and in any part of the processing chain. The following example shows how to intercept inbound messages from clients:

  • Java

  • Kotlin

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {

	@Override
	public void configureClientInboundChannel(ChannelRegistration registration) {
		registration.interceptors(new MyChannelInterceptor());
	}
}
@Configuration
@EnableWebSocketMessageBroker
class WebSocketConfiguration : WebSocketMessageBrokerConfigurer {

	override fun configureClientInboundChannel(registration: ChannelRegistration) {
		registration.interceptors(MyChannelInterceptor())
	}
}

一个自定义 ChannelInterceptor 可以使用 StompHeaderAccessorSimpMessageHeaderAccessor 来访问有关消息的信息,如下例所示:

A custom ChannelInterceptor can use StompHeaderAccessor or SimpMessageHeaderAccessor to access information about the message, as the following example shows:

  • Java

  • Kotlin

public class MyChannelInterceptor implements ChannelInterceptor {

	@Override
	public Message<?> preSend(Message<?> message, MessageChannel channel) {
		StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
		StompCommand command = accessor.getCommand();
		// ...
		return message;
	}
}
class MyChannelInterceptor : ChannelInterceptor {

	override fun preSend(message: Message<*>, channel: MessageChannel): Message<*> {
		val accessor = StompHeaderAccessor.wrap(message)
		val command = accessor.command
		// ...
		return message
	}
}

应用程序还可以实现 ExecutorChannelInterceptor,它是一个 ChannelInterceptor 的子接口,在处理消息的线程中有回调。当 ChannelInterceptor 每一消息被发送到一个通道时只会调用一次,ExecutorChannelInterceptor 在订阅通道中消息的每个 MessageHandler 的线程中提供钩子。

Applications can also implement ExecutorChannelInterceptor, which is a sub-interface of ChannelInterceptor with callbacks in the thread in which the messages are handled. While a ChannelInterceptor is invoked once for each message sent to a channel, the ExecutorChannelInterceptor provides hooks in the thread of each MessageHandler subscribed to messages from the channel.

请注意,就像前面所述的 SessionDisconnectEvent 一样,DISCONNECT 消息可以来自客户端,也可以在 WebSocket 会话关闭时自动生成。在某些情况下,拦截器可能会对每个会话拦截此消息多次。组件应针对多个断开连接事件具有幂等性。

Note that, as with the SessionDisconnectEvent described earlier, a DISCONNECT message can be from the client or it can also be automatically generated when the WebSocket session is closed. In some cases, an interceptor may intercept this message more than once for each session. Components should be idempotent with regard to multiple disconnect events.