XMPP网页聊天:如何解决多个选项卡/窗口的问题?

10
我们有一个网站,使用 strophe.js 库和 ejabberd XMPP 服务器为其开发了一个聊天系统。我们使用 PHP(使用内部库)进行会话附件的初始化。我们从 PHP 脚本获取 RID 和 SID,然后使用 strophe 的会话附件功能。所述的 RID 和 SID 存储在 cookie 中,并且每次 strophe.js 更新 RID 时,cookie 上的 RID 值也会更新。(这样我们就可以在页面刷新/导航到网站上的其他地方时重复使用 Session ID)
现在我们计划在多个选项卡/窗口中使用它。我观察了 Facebook 的实现,每个选项卡都有一个长轮询请求到特定域名。每个选项卡的域名都不同。例如,第一个选项卡可能是 0.86.channel.facebook.com。第二个选项卡可能是 1.86.channel.facebook.com。据我所知,这是为解决浏览器对某个域名最多只能有两个活动请求的限制。这个多域名解决方案是如何实现的?
接下来是关于聊天会话本身的问题。每个选项卡的聊天会话都应该是不同的,对吧?那么如何像 Facebook 那样将 UI 与每个选项卡同步?我的想法是,针对每个操作,向用户自己的 JID 发送包含与聊天相关的操作完成的消息。例如,打开聊天窗口会发送类似这样的消息:
<message from="my_own_jid" to="my_own_jid" type="chat">
    <body>{"jid-of-contact":"open-chat-box"}</body>
</message>

这将被聊天客户端捕获,并相应地调整用户界面(在这种情况下,为联系人打开聊天框)。

对于这个实现有任何建议/评论吗?

谢谢!


在多领域方面:不同的领域可以简单地将来自不同领域的请求重新路由回它们使用的XMPP服务器。这只是浏览器端的一种“伪装”。关于如何使用单个用户名登录相同资源,嗯,我想知道Facebook是否已经实现/修改了他们使用的XMPP服务器来实现这一点。这很有趣。 - DashK
关于在多个选项卡中保持UI的外观和感觉:我想知道您是否可以使用HTML5的数据存储来维护聊天的“状态”,并且每个选项卡只需响应数据存储中的更新?根据XMPP规范,您应该能够使用资源优先级来“控制”消息节将被发送到何处。不知道您是否可以利用它来实现多个选项卡的效果... - DashK
@DashK 他们是在同一资源上登录吗?我认为这是不同的会话,每个会话都有不同的资源。这样就不需要修改XMPP服务器(使用相同资源的同一用户进行多次登录违反了XMPP标准,对吧?)。 - putolaruan
关于HTML5数据存储,恐怕在不同的浏览器上实现得当之前我无法实现它(据我所知,只有基于Webkit的浏览器完全支持此功能)。关于资源优先级,您是在谈论XEP-0168吗?我稍微浏览了一下,开始看到它在多标签聊天的背景下可能的用途,但我仍然不太清楚。 - putolaruan
关于XEP-0168:我猜 - 我不确定的是,如果两个带有不同资源的会话具有相同的优先级,当有人向user@domain.com发送未指定资源的消息时,哪一个会收到消息? (还是两个都会收到?) - DashK
显示剩余2条评论
2个回答

8
我和我的团队正在处理与你们相同的问题 - 只是我们使用Openfire而不是Ejabberd(主要是因为我们具备Java技能但不熟悉Erlang)。我们公司正在开发浏览器游戏。
我们的解决方案包括:
- XMPPHP - 用于预绑定 - Strophe.js - 用于会话附加(改动过) - Punjab - 作为连接管理器(扩展、修改过) - Openfire - 作为XMPP服务器
我们使用Punjab,因为Openfire的BOSH实现似乎一开始就无法很好地与其他组件配合使用。
基本上,我们决定不为每个选项卡创建一个会话。这是因为我们的某些游戏的工作方式类似于通常的网站:单击链接将请求完全新的页面(而较新的游戏完全在ajax中工作,大多数GUI保持不变)。换句话说:我们基于Web的聊天必须在用户“移动网站”的环境下工作。一个选项卡的一个会话意味着每个页面请求都需要一个新的会话,这似乎是一个巨大的开销,因为玩家经常点击得相当快。因此,我们希望创建一个会话并让其针对一个用户。
为了解决这个问题,我们像您一样修改了strophe.js,以便在cookie中读取/保存RID,因此所有选项卡都知道当前的RID并递增到正确的值。另一件事是,我们让Strophe将CID添加到XMPP数据包的正文中。CID类似于客户端ID。我很快就会解释用法。
接下来计划修改punjab中的两个内容。首先,我们添加了一个类来替换punjab中通常存储等待请求的方式。等待的BOSH请求现在保存在一个字典中,其CID(strophe.js现在添加到每个请求的正文中)作为键。当来自同一标签页的另一个请求到达时,punjab就知道要向哪个等待请求发送空答复。如果有新的数据包要传送,则punjab将把这些数据包发送给字典中的所有等待请求。因此,传入的消息分发到所有选项卡。其次,我们添加了几行代码,以便从一个选项卡发送的消息立即“返回”到其他选项卡。因此,消息也可以出现在其他选项卡的历史记录中。
当然,还有其他问题需要解决,例如当玩家进入下一个屏幕时,不要丢失GUI中的聊天记录。将其存储在cookie中是不好的,因为所有这些内容都随着每个请求被发送出去,会导致大量的流量。为此,我们考虑实现类似于XEP-0136消息归档的东西。
总之,我们需要处理修补/扩展strophe.js和punjab,并且要对标准进行一些修改。但是现在它很好用,我很兴奋地看到这个设置在beta版中的表现。

我很好奇,Beta版本怎么样了?我这么问是因为我正准备开始一个类似的解决方案。 - Joshua Moore
1
你在 Github 上对 strophe/punjab 进行的修改是偶然的吗? - Aeon
我也很好奇。你能分享一下你在Strophe和Punjab上做的修改吗? - Kemal Fadillah

3

我的解决方案:

每个选项卡都有自己的连接,连接到不同的资源,全部具有1优先级。

在openfire中添加服务器变量route.all-resources: true
消息将广播到所有资源。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接