Django中基于XMPP的实时聊天系统

时间:2011-07-05 14:08:57

标签: python django xmpp bosh

我需要在Django中实现基于XMPP的实时聊天系统。经过同事的大量鞭打和想法后,我们想出了这个。


使用机器人的方法:

  • 当访问者访问该网站时。访问者的XMPP客户端(在本例中为Strophe.JS)开始与XMPP服务器的XMPP-over-BOSH连接,并连接到名为<visitor_id>@conference.demo.com的房间。目前房间里没有其他人。
  • 访问者向Django发送带有自定义访客ID的分析请求
  • Django视图将访客ID存储在名为ActiveUsers的表中。此表包含一个名为status的新字段。它将status设置为INACTIVE
  • 此模型在save方法上发送信号。
  • 此信号由连接到XMPP服务器并加入房间<visitor_id>@conference.demo.com的机器人拾取。现在我们在房间里有用户和机器人。
  • 网站支持人员登录其网络界面。
  • 他们有JS代码,可以长时间轮询Django站点来检查ActiveUsers。它从表中获取行并显示它。 (我已经考虑过使用django-pubsub
  • 当访问者键入消息时,它通过XMPP-over-BOSH进入XMPP服务器,房间中的jabber bot看到此消息并将ActiveUsers表中记录的状态更新为{{ 1}}。
  • 如上所述:网站支持人员有JS继续轮询此表。它开始闪烁显示用户正在聊天。
  • 支持人员现在可以双击该行,这样就开始了与访客房间的XMPP-over-BOSH连接。它知道房间是ACTIVE
  • 机器人看到支持人员已加入会议室,更新<visitor_id>@conference.demo.com记录以显示ActiveUsers。这确保了只有支持人员才能进入房间,即占用房间。
  • 机器人将消息记录到Django表
  • 当两者都看到两个用户都离开了房间时,它会删除记录。

ejabberd或openfire将是XMPP服务器。 Apache是​​运行mod_wsgi的Web服务器,用于服务Django和mod_proxy,用于代理XMPP-over-BOSh请求到XMPP服务器。

这听起来好像这样做吗?有什么建议?我担心Django系统的负载。

(很长。很抱歉'那个。)


使用Presence Stanzas的方法:

在客户端,我正在使用支持在线状态的Strophe JS库,并且我添加了回调方法。我很灵活使用ejabberd或openfire作为我的XMPP服务器。 XMPP服务器上有许多访问者 - 一些来自站点A,一些来自站点B,但它们都连接到同一个XMPP服务器。当访问者访问该站点时,他们将CHATTING连接到XMPP服务器,并且每个人都登录到名为<visitor_id>_<site_id>@demo.com的房间。销售/支持人员也以<visitor_id>@conference.demo.com的身份连接到XMPP服务器。但它们没有连接到任何聊天室。他们的名单上没有任何访客。

显示用户已连接到网站的一种好方法是将状态节传递给销售/支持人员。只有来自同一网站的访问者和销售/支持人员才能相互沟通,这就是为什么我在用户名中有<supportsale_id>_<site_id>@demo.com来显示该人所属的网站。

如果您的名单中没有他,您似乎无法订阅用户的状态节。 (很合乎逻辑)。是否可以自动将连接到系统的站点的每个新用户添加到该站点的销售/支持人员的名单中?这不会自动向销售/支持人员发出信号吗?我该如何实现这一点 - 任何帮助?

3 个答案:

答案 0 :(得分:2)

我正是这样写的。它被称为Seshat,并在网站和Jabber服务器之间使用“代理”机器人(我使用ejabberd)。它目前处于测试阶段,主要是因为它尚未在我公司外进行广泛测试。

注意:尽管README专门提到了Pyramid Web框架,但核心系统与Django,TurboGears或命令行系统一样可行。只是我只打包示例代码,展示如何将它与Pyramid集成。

Seshat正在积极开发中。如果您有任何功能请求,请告诉我们。 : - )

答案 1 :(得分:1)

我认为最好使用存在节来“表示”任何(in)活动。您需要存储在数据库中的只是进一步分析所需的持久数据。否则,我认为您将有充足的时间编写应用程序:)。

编辑:

function onConnect(status) {
  if (status == Strophe.Status.CONNECTED) {
    var joined = false;
    var participants = {};
    $('#events').html('<text class="textmainleft">XMPP connection established. Ready to rock n roll!</text>');
    connection.send($pres().c('priority').t('-1'));
    connection.addHandler(notifyUser, null, 'message', 'groupchat', null, null);
    connection.send($pres({to: 'groupchatroom@conference.demo.com/' + nickname}).c('x', {xmlns: 'http://jabber.org/protocol/muc'}));
  } else if (status == Strophe.Status.AUTHFAIL) {
    $(location).attr('href', AUTHFAIL_URL);
  } else if (status == Strophe.Status.CONNFAIL) {
    $(location).attr('href', AUTHFAIL_URL);
  }
}

$(document).ready(function () {
  connection = new Strophe.Connection(BOSH_SERVICE);
  connection.connect(jid, password, onConnect);
});

notifyUser是另一个处理收到的消息节的函数(只是链接onConnect)。

答案 2 :(得分:1)

我不确定您是否需要使用MUC来实现此功能。您的机器人可以维护自己订阅的pubsub节点。当新用户开始输入时,它可以向pubsub节点发送通知,然后机器人会看到该通知。从那里,机器人可以通过XMPP通知支持人员,从而消除了长时间轮询数据库表的需要。然后,支持人员可以与最终用户开始标准的一对一聊天会话。此外,他们的存在可以设置为'na',以表明他们正在与用户进行会话。