Cometd客户端不与cometD Server握手

时间:2019-01-05 16:24:44

标签: java spring-boot cometd

我是CometD的新手。我用Java和简单的CometD Client编写了一个基本的CometD Server。我从/ mana / handshake,/ meta / connect,/ meta / subscribe渠道获得邮递员的成功响应。但是,当我开始使用我的CometD Java客户端(从https://protect-us.mimecast.com/s/vLH6CNk58of1Ow1GsmVz4u?domain=github.com重用)时,握手失败,并显示以下消息。

  

失败{supportedConnectionTypes = [长轮询],   channel = / meta / handshake,id = 22,version = 1.0}

我在我的代码中使用了CometdVersion-'4.0.0',jettyVersion-'9.4.0.v20161208',springbootVersion-'1.5.14.RELEASE'。 我已经向AnnotationCometDServlet完成了动态servlet注册,并添加了/ notifications作为映射。 我在bayeuxServer配置类中创建了如下频道。

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

在客户端代码中,我已将/ notifications用作默认网址,并将通道用作/ 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 :(得分:0)

您有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}看起来像握手请求。因此,很难说出问题出在哪里,因为失败原因通常在握手回复中报告。

如果已在/notifications Servlet映射下动态注册CometD Servlet,则客户端应具有以/notifications结尾的URL。 请注意,Servlet映射/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通道),上面的代码还将通过/updatesdeliver()通道上向客户端发送另一个消息,因此客户端将在/updates频道上收到两条不同的消息。 这可能是您想要的,但大多数时候不是。 请阅读difference between broadcast channels and service channels

使用握手失败的详细信息更新问题,并对CometD,Jetty和Spring Boot使用一致的版本。