2017-08-15 85 views
1

我在Android上使用CometD Java客户端。向CometD添加自定义字段订阅消息

编译组: 'org.cometd.java',名称: '的cometd-Java的客户端',版本: '2.9.1'

我需要订阅的频道上CometD服务器。但是有一个问题 - 服务器需要自定义订阅消息(这是从服务器文档的预期订阅消息的有效载荷):

[ 
    { 
     "user": "xyz-WQUAq3shWho1ZcJHaibQYzCh2ILMMX1o-gA6NuehTFYMhvViv6Ow3dvPbyt8Zwg10-bd8bd779f107615b1c5a1470706e4050e5389ddc", 
     "domain": "xyz", 
     "pid": "gA6NuehTFYMhvViv6Ow3dvPbyt8Zwg10", 
     "sid": "85f103a2", 
     "gid": "WQUAq3shWho1ZcJHaibQYzCh2ILMMX1o", 
     "pageId": "6ea23e", 
     "entityId": "xyz", 
     "triggeringGoal": "3E955818355C44E2479B2A26629E69566C8C6376", 
     "chatSearchPattern": "ua.domain=xyz", 
     "startTime": 1482931626853, 
     "metadata": "{}", 
     "chatMetadata": "{}", 
     "language": "en", 

     "id": "3", 
     "channel": "\/meta\/subscribe", 
     "subscription": "\/chat\/xyz-WQUAq3shWho1ZcJHaibQYzCh2ILMMX1o-gA6NuehTFYMhvViv6Ow3dvPbyt8Zwg10-bd8bd779f107615b1c5a1470706e4050e5389ddc", 
     "clientId": "26l1v2ngpdcwdtno1wu30rk92dur4", 
     "ext": { 
     } 
    } 
] 

所以我的问题是我怎么添加到订阅消息自定义字段(userdomain,pid, sid等)?目前,我订阅频道这样的:

cometdClient.getChannel("/chat/" + clientID).subscribe(new ChannelListener("/chat/ messages"), new ChannelListener("/chat/ progress")); 

但预期它是失败的。

顺便说一下,我使用org.eclipse.jetty.client.HttpClient作为HttpClient。

回答

1

首先,您应该真正升级,因为CometD 2.9.1现在真的很老了,并且JDK 7在Android上受支持。

/meta/subscribe消息中需要所有这些字段的服务器的设计是错误的。 大多数信息是静态的(例如user和各种“cookies”,如pid等),并且可以在CometD握手时确定,因此在订阅期间不需要发送它。

此外,在/meta/subscribe消息期间发送消息使其受到攻击(例如,攻击者可以使用不同的user字段伪造消息)。您想要阅读CometD documentationsecurity section

此外,使用每个用户的频道(因为看起来频道名称是/chat/user字段的串联)不是推荐的方法,因为它可能创建可能的很多频道,而相同的功能可以通过单个服务通道(和user作为正在发送的消息的字段)可以更高效地实现。

如果你真的有这些字段添加到/meta/subscribe消息,这样做的方法是使用一个custom extension,沿着这些线路:

class SubscribeExtension extends ClientSession.Extension.Adapter { 
    @Override 
    public boolean sendMeta(ClientSession session, Message.Mutable message) { 
     if (Channel.META_SUBSCRIBE.equals(message.getChannel())) { 
      String subscription = (String)message.get(Message.SUBSCRIPTION_FIELD); 
      if (subscription.startsWith("/chat/") { 
       // Add fields. 
      } 
     } 
     return true; 
    } 
} 

最后,如果你真的需要添加额外的字段一个/meta/subscribe消息,你想这样做的ext领域内,在适当的命名空间:

{ 
    "id": "3", 
    "channel": "/meta/subscribe", 
    "subscription": "/chat/xyz-WQUAq3shWho1ZcJHaibQYzCh2ILMMX1o-gA6NuehTFYMhvViv6Ow3dvPbyt8Zwg10-bd8bd779f107615b1c5a1470706e4050e5389ddc", 
    "clientId": "26l1v2ngpdcwdtno1wu30rk92dur4", 
    "ext": { 
     "com.acme.myapp": { 
      "time": 1234567890, 
      "pageId": "6ea23e", 
      ... 
     } 
    } 
} 

注意额外的领域怎么办没有污染的消息本身,而是在分组字段名称空间com.acme.app这将代表您的公司和应用程序。

+0

感谢您指出其他的东西了。很遗憾,我无法升级。 2.9.1以上的所有内容在异常握手期间都会失败:exception = java.lang.NullPointerException:试图调用虚拟方法'javax.net.ssl.SSLEngine org.eclipse.jetty.util.ssl.SslContextFactory.newSSLEngine(java。郎。字符串,int)'空对象引用 –

+0

'NullPointerException'与CometD版本没有任何关系,它可能只是一些错误的配置或缺少调用'start()'方法来启动这些Jetty对象的生命周期。 – sbordet