在 Jetty/ASP.NET 中实现 CometD 的确认扩展

发布于 2025-01-04 23:48:32 字数 617 浏览 2 评论 0原文

我们使用 CometD 2 来实现中央数据提供者和使用数据的多个后端之间的连接。到目前为止,当其中一个后端短暂发生故障时,同时发布的所有消息都会丢失。现在我们听说了 CometD 的“确认扩展”。它应该创建一个服务器端消息列表,并在其中一个客户端报告重新上线时传递这些消息。这里有一些问题:

1)这也适用于多个客户端吗?

2)文档(http://cometd.org/documentation/2.x/cometd-ext/ack)说:“请注意,如果断开连接的浏览器断开连接的时间超过maxInterval(默认10秒),那么客户端将超时并且未确认的队列被丢弃。” ->这是否意味着如果我的客户端没有在 maxInterval 内恢复,消息无论如何都会丢失?

因此, 2.1) 最大maxInterval是多少?将其设置为高值会产生什么后果?

2.2)我们需要一个安全机制来防止至少几分钟的故障。这可能吗?还有其他选择吗?

3)真的只需要在客户端和cometD服务器中添加两个扩展吗?我们使用 Jetty 作为服务器,使用 .NET Oyatel 作为客户端。有人有这方面的经验吗?

我对这些问题感到抱歉,但不幸的是,CometD 项目并没有很好的记录。我真的很感激任何答案。

干杯, 克里斯

we're using CometD 2 to achieve the connection between a central data provider and several backends consuming the data. Up to now, when one of the backends fails briefly, all messages posted in the meantime are lost. Now we heard about the "Acknowledge Extension" for CometD. It is supposed to create a server-side list of messages and delivers them when one of the clients reports to be back online. Here are some questions:

1) Does this also work with several clients?

2) The documentation (http://cometd.org/documentation/2.x/cometd-ext/ack) says: "Note that if the disconnected browser is disconnected for in excess of maxInterval (default 10s), then the client will be timed out and the unacknowledged queue discarded." -> does this mean that in case my client doesn't restore within the maxInterval, the messages are lost anyway?

Hence,
2.1) What's the maximal maxInterval? Which consequences does it have to set it to a high value?

2.2) We'd need a secure mechanism for fail outs of at least a few minutes. Is this possible? Are there any alternatives?

3) Is it really only necessary to add the two extensions in both the client and cometD server? We're using Jetty for the server and .NET Oyatel for the client. Does anyone have some experiences with this?

I'm sorry for this bunch of questions, but unfortunately, the CometD project isn't really well documented. I really appreciate any answers.

Cheers,
Chris

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

樱娆 2025-01-11 23:48:32

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 中,简单地包含扩展就足够了(jQuery 的 dojo.require 或脚本包含) 。

当带有 AckExtension 的客户端连接到服务器时,将记录类似于以下内容的消息(来自我的 Jetty 控制台日志):

[qtp959713667-32] INFO  org.cometd.server.ext.AcknowledgedMessagesExtension  - Enabled message acknowledgement for client 51vkuhps5qgsuaxhehzfg6yw92

另一个注释,因为它可能不明显:ack 扩展只会提供服务器到客户端的传递保证,而不是客户端到服务器。也就是说,当您从客户端向服务器发布消息时,该消息可能无法到达服务器并且会丢失。

一旦消息到达服务器,ack 扩展将确保当时连接的所有收件人都将收到该消息(只要它们在 maxInterval 毫秒内不无法到达)。

如果您监听“/meta/unsuccessful”上的通知并重新发送消息(失败的原始消息作为 message.request 传递给处理程序),那么实现客户端重试相对简单。

1) Does this also work with several Clients

Yes, it does. There is one message queue allocated for each client (see AcknowledgedMessagesClientExtension).

2) does this mean that in case my client doesn't restore within the maxInterval, the messages are lost anyway?

Yes, it does. When the client can't reach the server for maxInterval milliseconds, the server will throw away all state associated with that client.

2.1) What's the maximal maxInterval? Which consequences does it have to set it to a high value?

maxInterval is a servlet parameter of the Cometd servlet. It is internally treated as a long value, so the maximal value for it is Long.MAX_VALUE.

Example configuration:

<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>

Setting it to a high value means that the server will wait longer before throwing away the state associated with a client (from the time the client stops contacting the server).

I see two problems with this. First, the memory requirements of the server will potentially be higher (which may also make denial of service easier). Second, the RemoveListener isn't called on the Server before the maxInterval expires, which may require you to implement additional logic that differentiates between "momentarily unreachable" and "disconnected".

2.2) We'd need a secure mechanism for fail outs of at least a few minutes. Is this possible? Are there any alternatives?

Yes, it is possible to configure the maxInterval to last for a few minutes.

An alternative would be to restore any server side state on every handshake. This can be achieved by adding a listener to "/meta/handshake" and publishing a message to a "/service/" channel (to make sure only the server receives the message), or by adding an additional property to the "ext" property of the handshake message. Be careful to let the client restore only valid state (sign it on the server if you must).

3) Is it really only necessary to add the two extensions in both the client and cometD server?

On the server it is sufficient to do something like:

bayeux.addExtension(new AcknowledgedMessagesExtension()); 

I don't know how you'd do it on Oyatel. In Javascript it suffices to simply include the extension (dojo.require or script include for jQuery).

When a client with the AckExtension connects to the server, a message similar to the following will be logged (from my Jetty console log):

[qtp959713667-32] INFO  org.cometd.server.ext.AcknowledgedMessagesExtension  - Enabled message acknowledgement for client 51vkuhps5qgsuaxhehzfg6yw92

Another note because it may not be obvious: the ack extension will only provide server to client delivery guarantee, not client to server. That is, when you publish a message from the client to the server, it may not reach the server and will be lost.

Once the message has made it to the server, the ack extension will ensure that all recipients connected at that time will receive the message (as long as they aren't unreachable for maxInterval milliseconds).

It is relatively straightforward to implement client-side retrying if you listen to notifications on "/meta/unsuccessful" and resend the message (the original message that failed is passed as message.request to the handler).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文