1) Работает ли это также с несколькими клиентами
Да, это так. Для каждого клиента выделена одна очередь сообщений (см. AcknowledgedMessagesClientExtension).
2) означает ли это, что если мой клиент не восстановится в maxInterval, сообщения все равно будут потеряны?
Да, это так. Когда клиент не может связаться с сервером в течение maxInterval миллисекунд, сервер отбрасывает все состояния, связанные с этим клиентом.
2.1) Какой максимальный maxInterval? Какие последствия это должно установить его на высокое значение?
maxInterval является параметром сервлета сервлета Cometd . Он внутренне обрабатывается как длинное значение, поэтому максимальное значение для него - 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>
Установка высокого значения означает, что сервер будет ждать дольше, прежде чем выбрасывать состояние, связанное с клиентом (с момента, когда клиент перестает связываться с сервером).
Я вижу две проблемы с этим. Во-первых, требования к памяти сервера могут быть выше (что также может облегчить отказ в обслуживании). Во-вторых, RemoveListener не вызывается на сервере до истечения срока действия maxInterval, что может потребовать от вас реализации дополнительной логики, которая различает «мгновенно недоступный» и «отключенный».
2.2) Нам понадобится безопасный механизм для отказов по крайней мере на несколько минут. Это возможно? Есть ли альтернативы?
Да, можно настроить maxInterval на несколько минут.
Альтернативой может быть восстановление любого состояния на стороне сервера при каждом рукопожатии. Этого можно достичь, добавив прослушиватель в «/ meta / handshake» и опубликовав сообщение в канал «/ service /» (чтобы убедиться, что сообщение получает только сервер), или добавив дополнительное свойство в «ext» свойство сообщения рукопожатия. Будьте внимательны, чтобы клиент мог восстановить только допустимое состояние (если необходимо, подпишите его на сервере).
3) Действительно ли необходимо только добавить два расширения как на клиенте, так и на сервере cometD?
На сервере достаточно сделать что-то вроде:
bayeux.addExtension(new AcknowledgedMessagesExtension());
Я не знаю, как бы ты это сделал на Оятеле. В Javascript достаточно просто включить расширение (dojo.require или скрипт include для jQuery).
Когда клиент с AckExtension подключается к серверу, будет записано сообщение, подобное следующему (из моего журнала консоли Jetty):
[qtp959713667-32] INFO org.cometd.server.ext.AcknowledgedMessagesExtension - Enabled message acknowledgement for client 51vkuhps5qgsuaxhehzfg6yw92
Еще одно замечание, поскольку оно может быть неочевидным: расширение ack будет предоставлять только гарантию доставки с сервера на клиент, а не с клиента на сервер. То есть, когда вы публикуете сообщение от клиента на сервер, оно может не попасть на сервер и будет потеряно.
Как только сообщение отправлено на сервер, расширение ack гарантирует, что все получатели, подключенные в это время, получат сообщение (если они недоступны в течение maxInterval миллисекунд).
Реализовать повторную попытку на стороне клиента довольно просто, если вы прослушиваете уведомления в "/ meta / unsuccessful" и повторно отправляете сообщение (исходное сообщение, которое не удалось, передается обработчику в виде message.request).