STOMP客户端中的心跳机制

3

我当前的踩踏客户端进程设计如下:

  1. 打开stomp连接(发送CONNECT帧)
  2. 订阅一个feed(发送SUBSCRIBE帧)
  3. 循环接收feed:
while (true) {
                connection.begin("txt1");

                    StompFrame message = connection.receive();
                    System.out.println("message get header"+message.toString());
                    LOG.info(message.getBody());

                    connection.ack(message, "txt1");

                connection.commit("txt1");

            }

我对这个过程的问题是我得到了

java.net.SocketTimeoutException: Read timed out
 at java.net.SocketInputStream.socketRead0(Native Method)...

我认为这主要是因为我订阅的信息源在某些时候(例如周末、节假日或晚上)发布信息较慢所致。
我已经在这里阅读了相关内容,我认为这可以解决我的问题。但是,我不确定如何将其与当前的stomp客户端布局相结合。我是否需要在第三步中发送一个CONNECT标头?
如果有帮助的话,我目前正在使用activemq创建我的stomp客户端。
在stomp 规范中,我们有:
关于心跳本身,通过网络连接接收到的任何新数据都表示远程端点是活动的。在某个方向上,如果每毫秒都期望有心跳信号:

  • 发送者必须每隔至少n毫秒通过网络连接发送新数据
  • 如果发送者没有真正的STOMP帧要发送,则必须发送单个换行符字节(0x0A)
  • 如果在至少n毫秒的时间窗口内,接收器没有接收到任何新数据,则可以将连接视为死亡
  • 由于定时不准确,接收器应该具有容错性并考虑误差范围

这是否意味着我的客户端需要每n秒发送一个换行符?


1
我同意,由于连接不活动,您可能会看到“读取超时”异常。您可以通过使用STOMP 1.1规范中提供的心跳功能来解决此问题。您正在使用哪个STOMP客户端库?请参见http://stomp.github.io/implementations.html#STOMP_Clients并选择支持STOMP 1.1的库,然后您将拥有启用心跳的API方法。 - Buchi
嗨@Buchi,感谢您的回复。我正在使用activemq作为我的STOMP客户端库,并使用this作为参考。目前,我在第1步(见上文)的标头中发送 heart-beat 0,2000,但我不知道接下来该去哪里。 - obsessiveCookie
我在你指出的测试程序中没有看到任何与心跳相关的代码。但是,我在Stomp.java类中看到了一些与心跳相关的常量。你应该检查库是否定期向代理发送心跳,否则,你将不得不自己添加。我猜ActiveMQ Java STOMP库并不是最新的,我也不认为它实现了STOMP 1.1。你可以寻找替代的Java STOMP库并进行实验。例如,参见https://github.com/mrstampy/Stampy - Buchi
我会做的。谢谢您的回复,@Buchi :) - obsessiveCookie
1
我仍然不清楚心跳如何工作。如果我发送 CONNECT heart-beat:0,1000 client-id:<client-id> passcode:<passcode> login:<login>,我会收到回复 CONNECTED heart-beat:1000,0 version:1.0 session:<login> server:ActiveMQ/5.8.0。如果我只在连接时执行此操作,我不知道如何监听心跳。 - obsessiveCookie
1个回答

6
您连接的Stomp服务器由于长时间没有活动而超时了您的连接。
如果服务器支持Stomp 1.1或更新版本,则客户端最简单的解决方案是在CONNECT的头部包含一个心跳指令,例如“0,10000”。这告诉服务器您无法发送心跳,但您希望它每10秒发送一次。这样,您就不需要实现它们,服务器将通过向您发送它们来保持连接活动。
当然,服务器将对客户端有自己的要求。在您的评论中,它以“1000,0”响应您的请求。这表示它将每1000毫秒发送一个心跳,并且它希望您不发送任何心跳,0表示根本没有。因此,您的工作量将很小。

嗨,罗伯特,这是否意味着当客户端使用“0,10000”连接时,客户端无需执行任何操作(如响应服务器的心跳)即可保持连接处于活动状态? - Tim
@Tim 如果服务器响应需要客户端发送心跳包,则客户端需要执行此操作。这取决于使用的服务器以及其配置方式。默认情况下,不需要客户端发送心跳包,因此客户端无需执行任何操作。 - Robert Newton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接