java - 向 CometD 订阅消息添加自定义字段

标签 java android cometd bayeux

我在 Android 上使用 CometD Java 客户端。

compile group: 'org.cometd.java', name: 'cometd-java-client', version: '2.9.1'

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

[
    {
        "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": {
        }
    }
]

所以我的问题是如何向订阅消息添加自定义字段(userdomainpidsid 等)?目前我正在订阅这样的 channel :

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

但它如预期的那样失败了。

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

最佳答案

首先,你真的应该升级,因为 CometD 2.9.1 现在真的很旧,Android 支持 JDK 7。

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

此外,在 /meta/subscribe 消息中发送它会使其容易受到攻击(例如,攻击者可以伪造具有不同 user 字段的消息)。您想阅读 security sectionCometD documentation

此外,不推荐为每个用户使用一个 channel (因为 channel 名称似乎是 /chat/user 字段的串联),因为它可能会创建很多 channel ,而使用单个服务 channel (和 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 下的 ext 字段中,这将代表您的公司和应用程序.

关于java - 向 CometD 订阅消息添加自定义字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45688991/

相关文章:

java - 为什么 junit 中的 assertEquals 和 assertSame 为同一类的两个实例返回相同的结果?

Java sl4j-log4j 日志记录库无法正常工作

java - 通知小图标颜色不是我设置的颜色

tomcat7 - Tomcat 错误 : java. lang.IllegalStateException:调用 [asyncPostProcess()] 对具有异步状态 [STARTED] 的请求无效

C http服务器编程

java - 数据完成后才返回响应

Java如何从udp数据包中的Sint64解析UTC

java - Android Camera.Parmaters 中的 fast-fps-mode - 如何访问和更改?

android - onReceive 异步操作和垃圾回收

java - 使用 CometD Java 客户端发布可由 Javascript 订阅者使用的消息