没有SockJS / StompJS的Spring STOMP服务器

时间:2017-04-20 14:26:37

标签: java stomp spring-websocket

我有Spring服务器支持Spring Websocket。我想使用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等命令来执行操作。

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

1 个答案:

答案 0 :(得分:1)

我已经解决了这个问题,所以简短的回答是是的,您可以使用Spring的STOMP消息而不使用SockJS ,只需将相应的构造消息发送到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);

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

webSocketConnection.Send("\n");

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

这是我们完全支持连接Spring没有SockJS的Websockets的基础,随时可以询问您是否还有其他问题。致Mateusz Gaffke求助和实施移动端的信用。