java - 如何在 Spring Boot 中从服务器任意发送到 STOMP 端点

标签 java spring-boot websocket kotlin stomp

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

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

我可以从 STOMP->STOMP 发送和REST->STOMP但我似乎无法使服务器直接正确地发送到 stomp 端点。

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

根据我收集的信息,我需要添加:

java

@Autowired
private SimpMessagingTemplate template;

Kotlin

@Autowired
lateinit var template: SimpleMessagingTemplate

进入我的一门类(class)并添加 @Controller@Service到类名列前茅,可能会成为openkotlin

尝试(java):

@Controller
public class STOMPDataListener implements SDDFDataListener {

    @Autowired
    private SimpMessagingTemplate template;


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

如果我在我的handleData上添加一个断点打电话我发现:

template = null

尝试(kotlin)

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

    @Autowired
    lateinit var template: SimpMessagingTemplate


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

lateinit property template has not been initialized enter image description here

如果我将其标记为

@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);
    }

}

非常感谢您的帮助。

最佳答案

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

如果使用 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 模板:SimpMessagingTemplate = ApplicationContextHolder.getContext().getBean(SimpMessagingTemplate::class.java)

这让我可以打电话:

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

关于java - 如何在 Spring Boot 中从服务器任意发送到 STOMP 端点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49367796/

相关文章:

java - 在 Java 中的类之间传递命令行参数

java - Java 中的字符串相等性

java - 为什么 findViewById 返回 null?

c# - 如何在 asp net core 中的服务之间共享 websocket

node.js 和 websocket 模块聊天没有返回数据

php - 没有守护进程的 PHP 中的 WebSocket 服务器?

java - 如何从 maven-archetype-webapp 工件生成 Ear 文件?

spring-boot - 内嵌Keycloak spring boot应用,将keycloak从12升级到14

java - Liquibase 未针对 Spring Boot/MySQL 应用程序执行

java - 为什么添加 @EnableAutoConfiguration 会导致 spring-boot 失败并显示 "Unable to find JPA packages to scan"