【问题标题】:How to send from server arbitrarily to a STOMP end point in SpringBoot如何在 Spring Boot 中任意从服务器发送到 STOMP 端点
【发布时间】:2018-08-28 07:09:27
【问题描述】:

我正在 SpringBoot 中编写一个桥接应用程序,其中两个将内部消息传递协议桥接到基于 websocket 的 stomp 设置。我在混合模式 Kotlinjava 项目中运行(这“可能”让事情变得困难)。

我的目标是当我在内部消息队列中收到一条消息时,我想将它发送到 STOMP 端点。

我可以从 STOMP->STOMPREST->STOMP 发送,但我似乎无法让服务器直接发送到 stomp 端点正确。

我几乎浏览了每一个堆栈帖子 - 我看到人们遇到了类似的问题,但是,我无法真正让列出的任何解决方案发挥作用。

根据我收集到的内容,我需要添加:

java

@Autowired
private SimpMessagingTemplate template;

科特林

@Autowired
lateinit var template: SimpleMessagingTemplate

进入我的一门课程,然后将@Controller@Service 添加到课程的顶部,可能在kotlin 中添加open

尝试(java):

@Controller
public class STOMPDataListener implements SDDFDataListener {

    @Autowired
    private SimpMessagingTemplate template;


    public void handleData(String source, SDDFCommonData data) {
        System.out.println("Received: " + data);
    }
}

如果我在 handleData 调用上添加断点,我会发现:

模板 = 空

尝试(科特林)

@Controller
class BridgeDataListener(val peerID: String = "default") : SDDFDataListener {

    @Autowired
    lateinit var template: SimpMessagingTemplate


    override fun handleData(source: String, data: SDDFCommonData) {
        println("Received: $data")
    }
}

lateinit 属性模板尚未初始化

如果我将其标记为

@Service
class BridgeDataListener(val peerID: String = "default") : SDDFDataListener {

我得到同样的错误。

我知道这是可能的,因为在文档中:https://docs.spring.io/spring/docs/4.0.1.RELEASE/spring-framework-reference/html/websocket.html 他们举了一个例子,但是,我不确定如何直接使用这个例子,因为我需要构建多个版本的 DataListeners - 并且从我了解您仅获得一份的@Autowired 课程吗?我可以让它成为一个单例还是会破坏一些东西?

@Controller
public class GreetingController {

    private SimpMessagingTemplate template;

    @Autowired
    public GreetingController(SimpMessagingTemplate template) {
        this.template = template;
    }

    @RequestMapping(value="/greetings", method=POST)
    public void greet(String greeting) {
        String text = "[" + getTimestamp() + "]:" + greeting;
        this.template.convertAndSend("/topic/greetings", text);
    }

}

非常感谢您的帮助。

【问题讨论】:

  • handleData 是如何调用的,即STOMPDataListener/BridgeDataListener 的实例是如何创建的? “通常”当 Spring 无法绑定到字段时,会引发异常。由于您不是这种情况,我怀疑该实例不是由 Spring 创建的。

标签: java spring-boot websocket kotlin stomp


【解决方案1】:

看来我最终解决了我的问题。

如果你用new 实例化一个类,@Autowired 不起作用。当我使用一些库时,我必须遵循https://stackoverflow.com/a/19896871/2069812中的方法#3

于是我建立了一个java类:

/**
 * See: https://stackoverflow.com/a/19896871/2069812
 */
@Component
public class ApplicationContextHolder implements ApplicationContextAware {
    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }

    public static ApplicationContext getContext() {
        return context;
    }
}

然后在我的数据处理程序类中,我通过以下方式访问了 bean:

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

这让我可以打电话:

 template.convertAndSend("/topic/sddf/$source", json.toString())
 template.convertAndSend("/topic/sddf/$source/$peerID", json.toString())

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 2021-02-08
    • 2017-05-27
    • 2019-04-22
    • 2021-04-22
    • 2014-05-27
    • 2018-07-17
    相关资源
    最近更新 更多