在一个请求中从 JS 到 Spring 的多个 STOMP 订阅

Posted

技术标签:

【中文标题】在一个请求中从 JS 到 Spring 的多个 STOMP 订阅【英文标题】:Multiple STOMP subscriptions from JS to Spring in one request 【发布时间】:2019-07-15 06:21:30 【问题描述】:

目标是使用 Web 界面和 Spring 框架进行多房间聊天。看起来STOMP 超过SockJS 是此类项目的最佳组合。 STOMP 基于目的地的订阅解决了所有广播问题。但是,如果用户一次使用 100 个(例如)聊天,我需要在他每次登录时从 Web 客户端发送 100 个订阅请求。

所以我正在寻找替代的单请求解决方案。让我把问题合并一下:

1) 有没有办法一次对多个订阅发出一个客户端 STOMP 请求?如果可以使用其他 JS 库发出这样的请求 - 那么我很乐意尝试。

2) 有没有办法从 Spring 后端发起订阅?在服务器端为一个客户端注册多个目标消息查询会很棒 - 我可以为此使用特殊请求或在登录期间执行此操作。

3) 关于这个问题还有其他建议吗?再说一遍:我很高兴尝试其他流行技术作为最后的手段。

下面的代码是最简单的回显服务。我只是在测试这个协议和技术。

基本客户端代码:

window.onload = function () 
    window.s = new SockJS("http://localhost:8080/portfolio");
    window.s.onopen = function () 
        window.stompClient = Stomp.over(window.s);

        stompClient.connect('admin', 'admin', function(frame) 
            console.log('Connected: ', frame);
            stompClient.subscribe('/topic/echo', function(messageOutput) 
                console.log(messageOutput.body);
            ), function(e)console.log("Fail My: ", e);)();
    ;
;

STOMP 配置:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer 

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) 
        registry.addEndpoint("/portfolio").setAllowedOrigins("*").withSockJS()
        .setClientLibraryUrl( "https://cdn.jsdelivr.net/npm/sockjs-client@1.3.0/dist/sockjs.min.js" );
    

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) 

        registry.enableSimpleBroker("/topic/");
        registry.setApplicationDestinationPrefixes("/app");
    

STOMP 控制器:

@Controller
public class GreetingController 

    @MessageMapping("/greetings")
    @SendTo("/topic/echo")
    public String handleMessage(@Payload String greeting) 
        System.out.println("[received]:" + greeting);
        return "[echo]: " + greeting;
    

【问题讨论】:

【参考方案1】:

The STOMP specification 表示 1 个SUBSCRIBE 帧与 1 个订阅相关。换句话说,没有办法为单个 SUBSCRIBE 框架获得多个订阅。

库/API 有可能(尽管在我看来不太可能)封装在一次调用中发送多个 SUBSCRIBE 帧的能力,但这只是一种方便的方法,实际上不会产生任何性能在协议层面受益。

【讨论】:

谢谢!关于 Java 端 SUBSCRIBE 启动有什么建议吗? 我不确定您所说的“订阅启动”是什么意思。我的回答解决了你的问题吗? 是的,答案解决了我的问题。我不能对你的回答做 (+1),因为我现在的声誉太低了。

以上是关于在一个请求中从 JS 到 Spring 的多个 STOMP 订阅的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Node.js 中从请求参数获取经过身份验证的用户到 socket.io

在 Spring Boot 中从 Angular 向后端发送 post 请求中的对象的问题

在开发模式 localhost 中从 Next.js 应用程序请求在不同端口上运行的 Graphql api

如何在一个请求中从 Binance API 获取所有(或多个)对的历史 klines?

在 Spring Boot 中从 jwt 获取附加属性

用于在 Spring Data Jpa 中从多个表中获取数据的自定义查询