如何在连接事件(SockJS,STOMP,Spring)上发送消息?

Ada*_*ski 5 spring sockjs spring-websocket

我通过STOMP通过SockJS连接到我的Spring后端。一切正常,所有浏览器等的配置都很好。但是,我找不到发送初始消息的方法。该方案如下:

  1. 客户端连接到主题
    函数connect(){
        var socket = new SockJS('http:// localhost:8080 / myEndpoint');
        stompClient = Stomp.over(socket);
        stompClient.connect({},function(frame){
            setConnected(true);
            console.log('Connected:'+ frame);
            stompClient.subscribe('/ topic / notify',function(message){
                showMessage(JSON.parse(message.body).content);
            });
        });
    }

后端配置大致如下所示:

    @组态
    @EnableWebSocketMessageBroker
    公共类WebSocketAppConfig扩展了AbstractWebSocketMessageBrokerConfigurer {   
    ...
    @Override
    公共无效registerStompEndpoints(最终StompEndpointRegistry注册表){
        Registry.addEndpoint(“ / myEndpoint”)。withSockJS();
    }

  1. 我想从后端(在连接事件上)向客户端发送自动答复,这样我就可以为他提供一些数据集(例如,从数据库中读取某物),而无需他(客户端)发送GET。请求(或其他任何请求)。综上所述,我只想在他连接之后向他发送有关SimMessagingTemplate对象的主题消息。

通常,当模板已经自动连线时,我会以以下方式执行此操作,例如在REST控制器中:

    @Autowired
    私有SimpMessagingTemplate模板;
    ...
    template.convertAndSend(主题,新消息(“成功!”));

如何在连接事件上实现这一目标?

更新

我设法使它起作用。但是,我对配置还是有些困惑。我将在此处显示2种配置如何发送初始消息:

1)第一个解决方案

JS部分

stompClient.subscribe('/app/pending', function(message){
    showMessage(JSON.parse(message.body).content);
});
stompClient.subscribe('/topic/incoming', function(message){
    showMessage(JSON.parse(message.body).content);
});
Run Code Online (Sandbox Code Playgroud)

Java部分

@Controller
public class WebSocketBusController {
    @SubscribeMapping("/pending")
Run Code Online (Sandbox Code Playgroud)

组态

@Override
public void configureMessageBroker(final MessageBrokerRegistry config) {
    config.enableSimpleBroker("/topic");
    config.setApplicationDestinationPrefixes("/app");
}
Run Code Online (Sandbox Code Playgroud)

...和其他电话

template.convertAndSend("/topic/incoming", outgoingMessage);
Run Code Online (Sandbox Code Playgroud)

2)第二种解决方案

JS部分

stompClient.subscribe('/topic/incoming', function(message){
    showMessage(JSON.parse(message.body).content);
})
Run Code Online (Sandbox Code Playgroud)

Java部分

@Controller
public class WebSocketBusController {
    @SubscribeMapping("/topic/incoming")
Run Code Online (Sandbox Code Playgroud)

组态

@Override
public void configureMessageBroker(final MessageBrokerRegistry config) {
    config.enableSimpleBroker("/topic");
    // NO APPLICATION PREFIX HERE
}
Run Code Online (Sandbox Code Playgroud)

...和其他电话

template.convertAndSend("/topic/incoming", outgoingMessage);
Run Code Online (Sandbox Code Playgroud)

摘要:

第一种情况使用两个订阅-我想避免这种情况,并认为只能使用一个订阅进行管理。

但是第二个没有应用前缀。但是至少我可以有一个订阅来侦听所提供的主题以及发送初始消息。

小智 5

如果您只想在连接时向客户端发送消息,请使用适当的 ApplicationListener:

@Component
public class StompConnectedEvent implements ApplicationListener<SessionConnectedEvent> {

    private static final Logger log = Logger.getLogger(StompConnectedEvent.class);

    @Autowired
    private Controller controller;

    @Override
    public void onApplicationEvent(SessionConnectedEvent event) {
        log.debug("Client connected.");
        // you can use a controller to send your msg here
    }
}
Run Code Online (Sandbox Code Playgroud)


Art*_*lan 3

您不能在 上执行此操作connect,但@SubscribeMapping在这种情况下 可以执行此操作。

您只需使用该注释标记服务方法,它就会向该subscribe函数返回结果。

来自 Spring 参考手册:

@SubscribeMapping 注释也可用于将订阅请求映射到 @Controller 方法。它在方法级别受支持,但也可以与类型级别 @MessageMapping 注释结合使用,该注释表示同一控制器内所有消息处理方法之间的共享映射。

默认情况下,@SubscribeMapping 方法的返回值作为消息直接发送回连接的客户端,而不通过代理。这对于实现请求-回复消息交互很有用;例如,在初始化应用程序 UI 时获取应用程序数据。或者,可以使用 @SendTo 注释 @SubscribeMapping 方法,在这种情况下,使用指定的目标目的地将生成的消息发送到“brokerChannel”。

更新

参考这个例子: https: //github.com/revelfire/spring4Test当调用index.html的第24行时,如何发送任何内容:stompClient.subscribe('/user/queue/socket/responses' ...来自弹簧控制器?

好吧,看起来像这样:

@SubscribeMapping("/queue/socket/responses")
public List<Employee> list() {
     return getEmployees();
}
Run Code Online (Sandbox Code Playgroud)

Stomp 客户端部分保持不变。