STOMP 客户端中的心跳
Posted
技术标签:
【中文标题】STOMP 客户端中的心跳【英文标题】:Heart-beating in STOMP client 【发布时间】:2014-04-12 16:10:55 【问题描述】:我目前的stomp客户端流程设计如下:
-
打开 stomp 连接(发送 CONNECT 帧)
订阅供稿(发送 SUBSCRIBE 框架)
执行循环以持续接收提要:
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)...
我认为这主要是因为我订阅的提要在某些时候提供的信息较慢(因为我通常在周末、节假日或晚上出现此错误)。
我一直在阅读这个here,我认为这将有助于解决我的问题。但是,我不太确定如何将它与我的 stomp 客户端的当前布局结合起来。我是否必须在第 3 步中发送 CONNECT 标头?
如果有帮助,我目前正在使用 activemq 创建我的 stomp 客户端。
在 stomp spec 我们有:
关于心跳本身,通过 网络连接表明远程端处于活动状态。在一个 给定方向,如果预计每毫秒心跳一次:
发送者必须至少每毫秒通过网络连接发送新数据 如果发送方没有真正的 STOMP 帧要发送,它必须发送一个换行字节 (0x0A) 如果在至少几毫秒的时间窗口内,接收器没有接收到任何新数据,它可以认为 连接失效 由于计时不准确,接收器应该容忍并考虑误差范围
这是否意味着我的客户需要每隔 n 秒发送一个换行符?
【问题讨论】:
我同意您会看到由于连接不活动而导致的“读取超时”异常。您可以使用 STOMP 1.1 规范中提供的心跳功能来解决此问题。您使用的是哪个 STOMP 客户端库?请参阅stomp.github.io/implementations.html#STOMP_Clients 并选择支持 STOMP 1.1 的那个,您将拥有启用心跳的 API 方法。 嗨@Buchi,谢谢你的回复。我使用 activemq 作为我的 STOMP 客户端库,并使用 this 作为我的参考。目前我在第 1 步的标题中发送heart-beat 0,2000
(见上文),但我不知道从那里去哪里
我在您指出的测试程序中没有看到任何与心跳相关的代码。但是,我在 Stomp.java 类中看到了一些与心跳相关的常量。您实际上应该检查库是否正在向代理发送定期心跳,否则,您必须自己添加它。我的猜测是 ActiveMQ Java STOMP 库不是最新的,我认为它也没有实现 STOMP 1.1。您可以寻找替代的 Java STOMP 库并进行试验。例如,请参阅github.com/mrstampy/Stampy
我会的。感谢您回复@Buchi :)
我仍然不清楚心跳是如何工作的。如果我发送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
我不明白如果我只在连接上这样做我怎么能听到心跳......
【参考方案1】:
由于不活动,您连接的 stomp 服务器已超时。
如果服务器支持 Stomp 1.1 或更高版本,对您的客户端最简单的解决方案是在 CONNECT 的标头中包含心跳指令,例如“0,10000”。这告诉服务器您不能发送心跳,但您希望它每 10 秒发送一次。这样您就不需要实现它们,服务器会通过将它们发送给您来保持连接处于活动状态。
当然服务器对客户端会有自己的要求。在您的评论中,它以“1000,0”响应您的请求。这表示它将每 1000 毫秒发送一次心跳,并且它希望您每 0 毫秒发送一次,0 表示根本没有。所以你的工作将是最小的。
【讨论】:
以上是关于STOMP 客户端中的心跳的主要内容,如果未能解决你的问题,请参考以下文章
基于 stomp.py 的持久客户端填充 ActiveMQ 中的订阅者列表