0

我创建了一个拥有约 50 个用户的应用程序。我正在尝试使用通道 API,但在测试消息发送时遇到了问题。我将令牌保存到数据库中,因此如果用户打开具有相同界面的多个选项卡并且我有一个 servlet 可以在令牌过期时重置我的令牌,我可以使用相同的令牌。

在我重新部署我的应用程序或更改我的应用程序版本之前,它工作正常。我停止接收消息。如果我尝试使用旧应用程序版本令牌打开一个频道,它不会抛出错误或任何东西,它会打开它,但我仍然没有在该频道上收到消息。
如果我重置我的令牌,它会再次正常工作。

有谁知道这个错误的解决方案,或者以前有人有过吗?我经常在人们工作时部署,所以我不能忽视它。

我最好的猜测是ChannelServiceFactory.getChannelService()返回一个不同的实例,ChannelService所以当我调用channelService.sendMessage("id","message");它时,它会将它发送到不同的通道。

4

1 回答 1

1

我无法解释为什么存储的令牌不能用于重新部署您的应用程序(它们应该),但我可以解释为什么它们在您更改版本时不起作用。简而言之,令牌特定于应用程序版本。

首先,这样做的原因:我们希望确保发送不同数据或更改消息格式或不同版本中的任何内容的应用程序不会跨版本边界发送消息。就像您不希望 v1 中的 javascript 包针对 v2 上的 servlet 呈现一样,您也不希望 v1 的 javascript 消息处理程序接收来自 v2 servlet 的消息(反之亦然)。

因此,希望能弄清楚发生了什么:

通道由您的 appid、您的应用版本和您在调用 createChannel 或 sendMessage 时提供的 clientid 的组合来标识。Channel API 的实现不存储任何 appid/clientid -> token 的映射。为了大大简化,您可以将 createChannel 视为执行以下操作:

public String createChannel(clientid) {
  // obviously we don't really just append strings to each other for actual implementation.
  return encryptStringSomehow(clientid + globalAppInfo.version + globalAppInfo.appid);
}

sendMessage 是这样的:

public void sendMessage(clientid, message) {
  // identify the JID used for this channel.
  JID xmppJid = new JID(mutateString(clientid + globalAppInfo.version + globalAppInfo.appid),
                        CHANNEL_XMPP_DOMAIN); // some domain used for channel messages
  // send the <message> stanza to that jid with the application message as the body
  xmppService.sendMessage(xmppJid, encodeSomehow(message));
}

在客户端,负责通道的 servlet 解密令牌并绑定到由与sendMessage函数相同的方法创建的 JID 标识的端点。

结果是令牌仅对从创建它们的同一版本的应用程序发送的消息有效。

于 2011-12-20T17:21:39.360 回答