首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Cometd客户端不与cometD服务器握手

Cometd客户端不与cometD服务器握手
EN

Stack Overflow用户
提问于 2019-01-05 16:24:43
回答 1查看 1.2K关注 0票数 1

我是CometD的新手。我用java和简单的CometD客户端编写了一个基本的CometD服务器,我得到了邮递员对/meta/握手、/meta/connect、/meta/订阅通道的成功响应。但是,当我开始使用我的cometD java客户机(我从https://protect-us.mimecast.com/s/vLH6CNk58of1Ow1GsmVz4u?domain=github.com中重用了它)时,握手失败了。

失败{supportedConnectionTypes=长轮询,通道=/meta/握手,id=22,version=1.0}

我在代码中使用cometdVersion - '4.0.0',jettyVersion - '9.4.0.v20161208',springbootVersion - '1.5.14.RELEASE‘。我对AnnotationCometDServlet进行了动态servlet注册,并添加了/notifications作为映射。我在bayeuxServer配置类中创建了一个如下所示的通道。

代码语言:javascript
复制
bayeuxServerImpl.createChannelIfAbsent("/updates", 
(ServerChannel.Initializer) channel -> channel.addAuthorizer(GrantAuthorizer.GRANT_ALL));

在客户端代码中,我使用/notifications作为默认值,使用通道作为/updates。

代码语言:javascript
复制
@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");
}
}
EN

回答 1

Stack Overflow用户

发布于 2019-01-05 18:26:36

CometD版本、Jetty版本和Spring版本有一个奇怪的组合。我建议您坚持在CometD POM中声明的默认版本控制,即CometD 4.0.2、Jetty9.4.14和SpringBoot2.0.6。

您提到的握手失败不是完整的,也不是失败的握手回复。这是因为握手回复有successful字段,您提到的{supportedConnectionTypes=[long-polling], channel=/meta/handshake, id=22, version=1.0}看起来像握手请求。因此,很难说出问题是什么,因为故障原因通常会在握手回复中报告。

如果您已经在CometD Servlet映射下动态注册了/notifications Servlet,那么客户机应该有一个以/notifications结尾的URL。注意,Servlet映射/notifications和CometD通道/notifications是两种不同的东西,它们没有关联--它们恰好有相同的名称。

您的代码大多很好,但是包含了一些错误。

代码语言:javascript
复制
@Configure({"/updates**,/notifications**"})
protected void configureChannel(ConfigurableServerChannel channel) {
    channel.addAuthorizer(GrantAuthorizer.GRANT_ALL);
    channel.addAuthorizer(GrantAuthorizer.GRANT_PUBLISH);
    channel.setPersistent(true);
}

以上代码必须是:

代码语言:javascript
复制
@Configure({"/updates/**,/notifications/**"})
protected void configureChannel(ConfigurableServerChannel channel) {
    channel.addAuthorizer(GrantAuthorizer.GRANT_ALL);
    channel.setPersistent(true);
}

请注意,通道全局必须在/之后。不需要在包含GRANT_PUBLISHGRANT_ALL之后使用GRANT_PUBLISH。配置方法应该是public,而不是protected

代码语言:javascript
复制
@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传递给方法。该方法可以更好地实现为:

代码语言:javascript
复制
@Listener("/updates")
public void handlesrgUpdates(ServerSession client, ServerMessage message) {
    client.deliver(serverSession, "/updates", "Received message back from client");
}

注意消息的“发送方”是如何作为类的字段注入的serverSession引用。

上面的代码仍然可能是错误的。由于/updates是广播信道,如果客户端订阅了/updates信道,当客户端向/updates信道发布消息时,它将从服务器接收消息(因为客户端订阅了/updates信道),上面的代码还将通过deliver()/updates信道上向客户端发送另一条消息,因此客户端将在/updates通道上接收两条不同的消息。这也许是你想要的,但大多数情况下并非如此。请在广播频道与服务频道的区别上读一读。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54053880

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档