Cometd Client не поддерживает связь с сервером CometD - PullRequest
0 голосов
/ 05 января 2019

Я новичок в CometD. Я написал базовый сервер CometD на Java и простой клиент CometD. Я получаю успешный ответ от почтальона для / meta / handshake, / meta / connect, / meta / subscribe каналов. Но когда я начинаю использовать свой Java-клиент cometD (который я повторно использовал с https://protect -us.mimecast.com / s / vLH6CNk58of1Ow1GsmVz4u? Domain = github.com ), рукопожатие завершается с сообщением ниже.

Failing {supportConnectionTypes = [длинный опрос], канал = / мета / рукопожатие, id = 22, версия = 1.0}

Я использую в своем коде cometdVersion - 4.0.0, jettyVersion - 9.4.0.v20161208, springbootVersion - 1.5.14.RELEASE. Я сделал динамическую регистрацию сервлета в AnnotationCometDServlet и добавил / уведомления как отображение. Я создал канал, как показано ниже в bayeuxServer классе конфигурации.

bayeuxServerImpl.createChannelIfAbsent("/updates", 
(ServerChannel.Initializer) channel -> channel.addAuthorizer(GrantAuthorizer.GRANT_ALL));

В коде клиента я использовал / уведомления как defaulturl и канал как / updates

@Service("cometListener")
@Slf4j
public class BayeuxListener implements BayeuxServer.SessionListener  {

@Inject
private BayeuxServer bayeuxServer;
@Session
private ServerSession serverSession;


@Configure({"/updates**,/notifications**"})
protected void configureChannel(ConfigurableServerChannel channel) {
    channel.addAuthorizer(GrantAuthorizer.GRANT_ALL);
    channel.addAuthorizer(GrantAuthorizer.GRANT_PUBLISH);
    channel.setPersistent(true);
}

@Listener("/meta/*")
public void monitorMeta(ServerSession session, ServerMessage message) {
    log.info("monitoring meta"+message.toString()+"channel "+message.getChannel()+"session id "+session.getId());
}

@Listener("/meta/subscribe")
public void monitorSubscribe(ServerSession session, ServerMessage message) {      
    log.info("Monitored Subscribe from " + session + " for " + message.get(Message.SUBSCRIPTION_FIELD));
}

@Listener("/meta/unsubscribe")
public void monitorUnsubscribe(ServerSession session, ServerMessage message) {
    log.info("Monitored Unsubscribe from " + session + " for " + message.get(Message.SUBSCRIPTION_FIELD));
}

@Listener("/updates")
public void handlesrgUpdates(ServerSession client, ServerMessage message) {
    ServerSession cilentSession = bayeuxServer.getSession(client.getId());
    client.deliver(cilentSession,"/updates", "Received message back from client");
}
}

1 Ответ

0 голосов
/ 05 января 2019

У вас странное сочетание версии CometD, версии Jetty и версии Spring Boot. Я рекомендую придерживаться версии по умолчанию, объявленной в CometD POM , то есть CometD 4.0.2, Jetty 9.4.14 и Spring Boot 2.0.6.

Указанная вами ошибка рукопожатия не завершена или не является ошибочным ответом. Это потому, что ответы на рукопожатие имеют поле successful, а то, что вы упоминаете {supportedConnectionTypes=[long-polling], channel=/meta/handshake, id=22, version=1.0}, выглядит как запрос на рукопожатие. Таким образом, трудно сказать, в чем проблема, потому что причина сбоя обычно указывается в ответе на рукопожатие.

Если вы динамически зарегистрировали сервлет CometD в соответствии с отображением сервлета /notifications, то клиент должен иметь URL-адрес, заканчивающийся /notifications. Обратите внимание, что отображение сервлета /notifications и канал CometD /notifications являются двумя разными вещами и не связаны между собой - они просто имеют одно и то же имя.

Ваш код в основном в порядке, но содержит несколько ошибок.

@Configure({"/updates**,/notifications**"})
protected void configureChannel(ConfigurableServerChannel channel) {
    channel.addAuthorizer(GrantAuthorizer.GRANT_ALL);
    channel.addAuthorizer(GrantAuthorizer.GRANT_PUBLISH);
    channel.setPersistent(true);
}

Вместо этого код должен быть:

@Configure({"/updates/**,/notifications/**"})
protected void configureChannel(ConfigurableServerChannel channel) {
    channel.addAuthorizer(GrantAuthorizer.GRANT_ALL);
    channel.setPersistent(true);
}

Обратите внимание, что глобализация канала должна быть после /. Нет необходимости GRANT_PUBLISH после GRANT_ALL, включая GRANT_PUBLISH. Метод конфигурации должен быть public, а не protected.

@Listener("/updates")
public void handlesrgUpdates(ServerSession client, ServerMessage message) {
    ServerSession cilentSession = bayeuxServer.getSession(client.getId());
    client.deliver(cilentSession,"/updates", "Received message back from client");
}

Нет необходимости извлекать clientSession из bayeuxServer, поскольку он уже передан в качестве параметра client методу. Метод может быть лучше реализован как:

@Listener("/updates")
public void handlesrgUpdates(ServerSession client, ServerMessage message) {
    client.deliver(serverSession, "/updates", "Received message back from client");
}

Обратите внимание, что «отправитель» сообщения - это ссылка serverSession, которая была введена как поле класса.

Приведенный выше код все еще, возможно, неверен. Поскольку /updates является широковещательным каналом, если клиент подписан на канал /updates, когда клиент публикует сообщение на канале /updates, он получит его обратно с сервера (поскольку клиент подписан на /updates (канал), а код выше также отправит другое сообщение клиенту по каналу /updates через deliver(), поэтому клиент получит два разных сообщения по каналу /updates. Это может быть то, что вы хотите, но в большинстве случаев это не так. Пожалуйста, ознакомьтесь с разницей между каналами вещания и служебными каналами .

Обновите вопрос, указав сведения о сбое рукопожатия, и используйте согласованные версии для CometD, Jetty и Spring Boot.

...