向CometD添加自定义字段订阅消息
我在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": {
}
}
]
所以我的问题是我怎么添加到订阅消息自定义字段(user
,domain
,pid
, sid
等)?目前,我订阅频道这样的:
cometdClient.getChannel("/chat/" + clientID).subscribe(new ChannelListener("/chat/ messages"), new ChannelListener("/chat/ progress"));
但预期它是失败的。
顺便说一下,我使用org.eclipse.jetty.client.HttpClient
作为HttpClient。
首先,您应该真正升级,因为CometD 2.9.1现在真的很老了,并且JDK 7在Android上受支持。
在/meta/subscribe
消息中需要所有这些字段的服务器的设计是错误的。 大多数信息是静态的(例如user
和各种“cookies”,如pid
等),并且可以在CometD握手时确定,因此在订阅期间不需要发送它。
此外,在/meta/subscribe
消息期间发送消息使其受到攻击(例如,攻击者可以使用不同的user
字段伪造消息)。您想要阅读CometD documentation的security 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
这将代表您的公司和应用程序。
感谢您指出其他的东西了。很遗憾,我无法升级。 2.9.1以上的所有内容在异常握手期间都会失败:exception = java.lang.NullPointerException:试图调用虚拟方法'javax.net.ssl.SSLEngine org.eclipse.jetty.util.ssl.SslContextFactory.newSSLEngine(java。郎。字符串,int)'空对象引用 –
'NullPointerException'与CometD版本没有任何关系,它可能只是一些错误的配置或缺少调用'start()'方法来启动这些Jetty对象的生命周期。 – sbordet