【问题标题】:Spring Websocket: How intercept a message sent by SimpMessagingTemplate through any either convertAndSend or convertAndSendToUser methods?Spring Websocket:如何通过任何 convertAndSend 或 convertAndSendToUser 方法拦截 SimpMessagingTemplate 发送的消息?
【发布时间】:2018-05-25 16:37:44
【问题描述】:

对于Spring Websocket

我有以下并且工作正常:

private final SimpMessagingTemplate simpMessagingTemplate;

...

@Scheduled(cron="some expression")
public void sendNotification() {
    logger.info("sendNotification ...");

    simpMessagingTemplate.convertAndSend(
            "/topic/something", 
            new Notification(...));

    logger.info("... sendNotification");
}

代码运行良好。所有订阅该Topic 的客户(我正在与ActiveMQ 合作)都能够看到发送的消息。

自定义类

@Component
class MessageChannelInterceptorAdapter extends ChannelInterceptorAdapter {

@Override 的所有方法都是为了拦截而创建的。

这个MessageChannelInterceptorAdapter 类注册关于基础设施如下:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Autowired
    @Qualifier("messageChannelInterceptorAdapter")
    private ChannelInterceptorAdapter messageChannelInterceptorAdapter;

...

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.interceptors(messageChannelInterceptorAdapter);
        WebSocketMessageBrokerConfigurer.super.configureClientInboundChannel(registration);
    }

    @Override
    public void configureClientOutboundChannel(ChannelRegistration registration) {
        registration.interceptors(messageChannelInterceptorAdapter);
        WebSocketMessageBrokerConfigurer.super.configureClientOutboundChannel(registration);
    }

...

即使应用程序运行良好。通过SimpMessagingTemplate发送的消息永远不会被MessageChannelInterceptorAdapter截获。

注意:MessageChannelInterceptorAdapter 类可以很好地拦截Stomp 事件,但同样不适用于SimpMessagingTemplate

因此:如何拦截SimpMessagingTemplate 通过convertAndSend 或convertAndSendToUser 方法发送的任何消息?

缺少什么?缺少有关基础架构的配置或创建其他扩展特定 Spring 类的类。

【问题讨论】:

  • 有任何进展吗?
  • @Jeef 是的,关于SimpMessagingTemplate,拦截器仅在存在客户端侦听Destination 时仅按预期工作。因为在我的情况下它是Topic,并且没有消费者,所以消息被发送但丢失了,拦截器永远不会工作。

标签: spring spring-websocket


【解决方案1】:

据我所知,没有简单的方法可以做到这一点。我有一种情况,我直接调用模板(就像你一样)。当我迁移到使用外部 STOMP 代理时,我突然发现我的一些调用不再有效:

当您使用 Rabbit 时,/topic/sddf/traffic 不再是有效目的地

我考虑编写自己的 SimpMessagingTemplate 类版本,这变得太难了 - 所以我不得不手动更改所有调用。

我的例子是 Kotlin 而不是 Java

我的解决方案是选择这个课程:

@Component
@Configurable
class MessagingTemplateWrapper{

    var template: SimpMessagingTemplate = ApplicationContextHolder.getContext().getBean(SimpMessagingTemplate::class.java)
    private val log = LoggerFactory.getLogger(BridgeDataListener::class.java)

    fun convertAndSend(dest: String, data: Any) {

        val rabbitDestination = dest.substring(0,11) + dest.substring(11).replace("/",".")
        template.convertAndSend(rabbitDestination, data)
    }
}

在我使用模板的任何地方我都这样做了:

//    var template: SimpMessagingTemplate = ApplicationContextHolder.getContext().getBean(SimpMessagingTemplate::class.java)
var template: MessagingTemplateWrapper = ApplicationContextHolder.getContext().getBean(MessagingTemplateWrapper::class.java)

所以我只是有一个包装器来做(也许)你想要的。

我不喜欢这个解决方案 - 但它确实有效。

【讨论】:

    猜你喜欢
    • 2016-12-19
    • 1970-01-01
    • 2020-03-18
    • 1970-01-01
    • 2022-01-09
    • 2015-09-27
    • 2018-09-08
    • 1970-01-01
    • 2014-07-27
    相关资源
    最近更新 更多