没有 SockJS/StompJS 的 Spring STOMP 服务器

Posted

技术标签:

【中文标题】没有 SockJS/StompJS 的 Spring STOMP 服务器【英文标题】:Spring STOMP server without SockJS/StompJS 【发布时间】:2017-09-17 06:04:36 【问题描述】:

我有支持 Spring Websocket 的 Spring 服务器。我想使用 STOMP 子协议来处理 web 套接字上的通信,所以 STOMP 端点的配置如下:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer 

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) 
        registry.addEndpoint("/chat")
                .setAllowedOrigins("*")
                .withSockJS();
    

Spring 文档和基本上我能找到的有关该主题的任何资源都显示了如何使用 SockJS + StompJS 创建 STOMP 客户端。它可以工作,但据我所知,它根本不需要 - 因为 STOMP 只是一个子协议,我应该能够通过使用 STOMP 消息语法基本上从任何 Web 套接字客户端与我的服务器通信。

假设我只想从 Google Chrome Simple Web Socket Client 插件连接到我的 STOMP 服务器。根据 STOMP 规范,我做的第一件事就是打开 Web 套接字连接。我用

ws://my.server.here/chat/websocket

链接。这部分有效,我的连接已建立。现在我想使用 STOMP。再次正如 STOMP 规范所说,我现在应该发送如下所示的 CONNECT 命令(STOMP 1.1):

CONNECT
accept-version:1.0,1.1
host:my.host.here

^@

然后我希望服务器使用 CONNECTED 命令响应,但我什么也没得到。如果不是“CONNECT”,我将使用一些不存在的命令,如“WRONG_COMMAND”,那么我可以看到关于未知命令的 Spring 异常被抛出,所以我想我的消息命中了 Spring 的 Websocket 内部,但我无法得到任何东西。如果这可行,我想使用后续的 SEND、SUBSCRIBE 等命令来执行操作。

这种工作流程是否可行?是我做错了什么,还是我错误地理解了整个想法及其运作方式?

【问题讨论】:

这个问题你解决了吗? 我没有使用 Google Websocket Client 解决它,但我在不使用 SockJS 的情况下通过移动应用程序使其工作。我发布了带有更详细描述的完整答案。如果您有任何其他问题,请随时询问。 【参考方案1】:

我已经解决了这个问题,所以简短的回答是是的,你可以在没有 SockJS 的情况下使用 Spring 的 STOMP 消息传递,只需向 websocket 端点发送适当的构造消息。

更长的答案是我无法使用 Google Simple Websocket Client 执行此操作,因为 STOMP 语法中的 ^@ 字符意味着,引用 STOM 文档:

本文档中的示例将使用 ASCII 中的 ^@、control-@ 来表示 NULL 八位字节。

我认为,Google 的 Websocket 客户端的问题在于,我真的无法用它发送这个空八位字节,所以我的 STOMP 消息没有正确终止。

我需要它用于无法使用 SockJS 的移动应用程序的简单聊天,在我公司移动开发人员的帮助下,我们能够编写工作解决方案,它基本上只是一个与 STOMP 子协议兼容的消息格式化程序。

我们使用 Xamarin 和 C# 进行移动应用开发。像这样连接到 STOMP。请注意,我们首先打开到 websocket 的常规连接,然后在它建立后进行 STOMP 处理:

var connectString = String.Format("CONNECT\naccept-version:1.0,1.1\nlogin:0\nheart-beat:30000,0\n\n\0", AuthService.TOKEN);
webSocketConnection = Websockets.WebSocketFactory.Create();
webSocketConnection.OnOpened += () => 

    webSocketConnection.Send(connectString);
    Debug.WriteLine("opened");
;

您必须使用客户端 onMessage 方法或等效方法来处理来自服务器的响应。建立连接后,您可以发送这样的 STOMP 消息,例如我们在应用中执行的操作:

var messageString = String.Format("SEND\ndestination:/app/chat/send/0\nlogin:1\n\n\"message\":\"2\"\n\0", chatName, AuthService.TOKEN, message);
webSocketConnection.Send(messageString);

还请记住,您可能需要支持心跳,因此后端不会以为您的应用程序已死而断开连接。在我们的移动应用程序中,我们从另一个线程发送心跳。心跳只是发送到 websocket 地址的换行消息。请注意,它不包含任何 STOMP 标头等:

webSocketConnection.Send("\n");

我们使用this 作为我们的 websocket 客户端。

这只是我们在没有 SockJS 的情况下完全支持与 Spring 的 Websockets 连接的基础,如果您有其他问题,请随时询问。感谢 Mateusz Gaffke 帮助和实施移动端。

【讨论】:

嗨,我的朋友,我的项目中遇到了同样的问题。后端弹簧靴和前端 - 颤动。我在 Spring Boot 中的 websocket 配置中的配置略有不同,其中包括 rabbitmq 作为代理。但问题是完全一样的。我只想知道你有没有在后端改变任何东西?其次,我们是否必须根据您上面描述的条件更改我们的颤振配置@Plebejusz 提前感谢

以上是关于没有 SockJS/StompJS 的 Spring STOMP 服务器的主要内容,如果未能解决你的问题,请参考以下文章

Sprin Boot无RunWith注解解决办法

cas完全是sprin框架写的么

Sprin学习一

sprin boot 配置文件的获取顺序

Sprin中Bean的顺序

SPRIN06_源码之核心组件接口BeanDefinitionDebug创建流程流程图总结