【问题标题】:XMPP based live-chat system in DjangoDjango中基于XMPP的实时聊天系统
【发布时间】:2011-09-28 20:48:04
【问题描述】:

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


使用机器人的方法:

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

ejabberd 或 openfire 将是 XMPP 服务器。 Apache 是一个 web 服务器,它运行 mod_wsgi 为 Django 提供服务,mod_proxy 将 XMPP-over-BOSh 请求代理到 XMPP 服务器。

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

(很长。抱歉。)


使用存在节的方法:

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

显示用户已连接到该网站的一个好方法是将一个存在节传递给销售/支持人员。只有来自同一站点的访问者和销售/支持人员才能相互交流,这就是为什么我在用户名中使用 <site_id> 来显示该人所属的站点。

如果您的花名册上没有用户,您似乎无法为该用户订阅出席信息节。 (非常合乎逻辑)。是否可以自动将连接到系统的站点的每个新用户添加到该站点的销售/支持人员名册中?这不会自动向销售/支持人员发出存在信号吗?我该如何实现这个——有什么帮助吗?

【问题讨论】:

    标签: python django xmpp


    【解决方案1】:

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

    注意:虽然自述文件特别提到了 Pyramid Web 框架,但核心系统也可以与 Django、TurboGears 或命令行系统一起使用。只是我只打包了示例代码,展示了如何将其与 Pyramid 集成。

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

    【讨论】:

    • 整洁!在我对this question 的回答中引用,也许您有一些有用的细节要添加? :)
    【解决方案2】:

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

    【讨论】:

    • 嗨,迈克。我没有完全跟上。我对这整件事很陌生,所以我很迷茫。当访问者开始键入时,它向 DB 发出 AJAX 请求?非常感谢。
    • 嘿,Mridang。您可以使用 IQ 节(请求/响应的 XMPP 版本)通过 BOSH 发送通知。 Strophe 提供了执行此操作的接口。您应该查看 XEP-0060 Pubsub,因为它可能包含一些对您有用的信息。此外,新用户应该能够向您的机器人发送定向出席信息(基本上是带有“to”属性的出席信息节),即使他们不在机器人的名单上。这样机器人就会知道用户的存在。
    • 嗨,迈克。我现在有点了解整个想法,但我正试图消除机器人。这是一个笨拙的实现。我昨天在我的帖子上做了一个eit,我不知道你是否看到了它。请看第二部分。当用户登录时,我可以向所有销售/支持人员发送出席信息,但他们需要在访问者的名册上,对吗?我怎样才能做到这一点?这行得通吗?
    • 我仍然认为你可以用 pubsub 做到这一点。用户都可以发布到一个公共节点,支持人员可以订阅它。然后,当用户登录时,将通知支持人员的客户。然后,他们的客户端将连接到聊天室,或者您可以让他们与用户进行常规 IM 会话。此外,您可以为每个 site_id 设置一个单独的节点,从而进一步分隔站点。
    • 另外,如果您的所有 JID 都提前知道,您可以在服务器的数据库中设置名册。这样,当用户连接他们的名册时,一切准备就绪。名册订阅可以是“to”、“from”或“both”类型,因此您可以阻止用户接收来自所有支持人员的出席信息,但可以允许支持人员查看所有登录用户。就像我说的那样,这只有在您可以提前设置名册时才有效。
    【解决方案3】:

    我认为最好使用存在节来“指示”任何(不)活动。您需要存储在数据库中的只是进一步分析所需的持久数据。否则,我认为您将在编写应用程序时玩得很开心:)。

    编辑:

    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)。

    【讨论】:

    • 嗨乔吉。你说得对。使用存在节将是最好的解决方案。你能看看我的编辑吗?谢谢。
    • 每个 MUC 房间都需要一个机器人。一旦访客加入房间,使用 Strophe connection.connect( jid, password, onConnect); 的连接方法并在 onConnect 函数中,向房间(出席)发送消息。机器人将接收节并将其(可能已修改,消息节)转发给支持人员。因此,他们会知道访客加入了哪个房间。
    • Gjorgji,您知道是否可以向服务器上的其他用户发送状态通知,即所有销售/支持人员,例如salessupportguy*_site_1@demo.com。 (* 是通配符)。不过,访问者不会拥有名册上的所有销售/支持人员。
    • 查看我编辑的答案。您还应该考虑向 MUC 房间中的机器人发送消息节,提醒他有人加入了对话。您的所有问题都在professionalxmpp.com 中得到解答,我强烈推荐。
    猜你喜欢
    • 2021-03-08
    • 1970-01-01
    • 1970-01-01
    • 2011-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-19
    • 2012-05-03
    相关资源
    最近更新 更多