2017-08-15 84 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