1)这是否也适用于多个客户
是的,它确实。为每个客户端分配一个消息队列(请参阅 AcknowledgedMessagesClientExtension)。
2)这是否意味着如果我的客户端没有在 maxInterval 内恢复,消息无论如何都会丢失?
是的,它确实。当客户端在 maxInterval 毫秒内无法到达服务器时,服务器将丢弃与该客户端关联的所有状态。
2.1) 最大的 maxInterval 是多少?将其设置为高值有什么后果?
maxInterval 是Cometd servlet的一个 servlet 参数。它在内部被视为长值,因此它的最大值是 Long.MAX_VALUE。
示例配置:
<init-param>
<!-- The max period of time, in milliseconds, that the server will wait for
a new long poll from a client before that client is considered invalid
and is removed -->
<param-name>maxInterval</param-name>
<param-value>10000</param-value>
</init-param>
将其设置为较高的值意味着服务器在丢弃与客户端关联的状态之前将等待更长的时间(从客户端停止联系服务器的时间开始)。
我看到这有两个问题。首先,服务器的内存要求可能会更高(这也可能使拒绝服务更容易)。其次,在 maxInterval 到期之前不会在服务器上调用 RemoveListener,这可能需要您实现额外的逻辑来区分“暂时无法访问”和“断开连接”。
2.2) 我们需要一个安全的机制来解决至少几分钟的故障。这可能吗?有没有其他选择?
是的,可以将 maxInterval 配置为持续几分钟。
另一种方法是在每次握手时恢复任何服务器端状态。这可以通过向“/meta/handshake”添加侦听器并将消息发布到“/service/”通道(以确保只有服务器接收消息)或向“ext”添加附加属性来实现握手消息的属性。小心让客户端只恢复有效状态(如果必须在服务器上签名)。
3)真的只需要在客户端和cometD服务器中都添加这两个扩展吗?
在服务器上,执行以下操作就足够了:
bayeux.addExtension(new AcknowledgedMessagesExtension());
我不知道你会如何在 Oyatel 上做到这一点。在 Javascript 中,只需包含扩展名(dojo.require 或 jQuery 的脚本包含)就足够了。
当带有 AckExtension 的客户端连接到服务器时,将记录类似于以下的消息(来自我的 Jetty 控制台日志):
[qtp959713667-32] INFO org.cometd.server.ext.AcknowledgedMessagesExtension - Enabled message acknowledgement for client 51vkuhps5qgsuaxhehzfg6yw92
另一个注意事项,因为它可能并不明显:ack 扩展只会提供服务器到客户端的传递保证,而不是客户端到服务器。也就是说,当你从客户端向服务器发布消息时,它可能无法到达服务器,会丢失。
一旦消息到达服务器,ack 扩展将确保当时连接的所有收件人都将收到消息(只要它们在 maxInterval 毫秒内不可达)。
如果您在“/meta/unsuccessful”上收听通知并重新发送消息(失败的原始消息作为 message.request 传递给处理程序),则实现客户端重试相对简单。