Система живого чата на основе XMPP в Джанго
Мне нужно внедрить систему живого чата на основе XMPP в Django. После долгих раздумий и идей от коллеги мы придумали это.
Метод с использованием бота:
- Когда посетитель посещает сайт. Клиент XMPP посетителя, в данном случае это Strophe.JS, начинает соединение XMPP-over-BOSH с сервером XMPP и подключается к комнате, называемой
<visitor_id>@conference.demo.com
, В настоящее время в комнате больше никого нет. - Посетитель делает запрос на аналитику с пользовательским идентификатором посетителя в Django.
- Представление Django хранит идентификатор посетителя в таблице с именем
ActiveUsers
, Эта таблица содержит также новое поле с именемstatus
, Это устанавливаетstatus
вINACTIVE
, - Эта модель отправляет сигнал на
save
метод. - Этот сигнал принимается ботом, который подключается к серверу XMPP и входит в комнату
<visitor_id>@conference.demo.com
, Теперь у нас есть пользователь и бот в комнате. - На сайте поддержки люди заходят в свой веб-интерфейс.
- У них есть код JS, который продолжает опрашивать сайт Django, чтобы проверить
ActiveUsers
, Он выбирает строки из таблицы и отображает их. (Я думал об использовании django-pubsub для этого) - Когда посетитель набирает сообщение, оно отправляется через XMPP-over-BOSH на сервер XMPP, бот-джаббер в комнате видит это сообщение и обновляет статус записи в
ActiveUsers
стол кACTIVE
, - Как сказано: у людей поддержки сайта есть JS, который продолжает опрашивать эту таблицу. Он начинает мигать, показывая, что пользователь сейчас общается.
- Персонал службы поддержки теперь может дважды щелкнуть по этой строке, которая при этом начинает соединение XMPP-over-BOSH с комнатой посетителя. Он знает, что комната
<visitor_id>@conference.demo.com
, - Бот, видящий, что человек поддержки присоединился к комнате, обновляет
ActiveUsers
запись, чтобы показатьCHATTING
, Это гарантирует, что в комнате может находиться только вспомогательный персонал, то есть занятая комната. - Бот записывает сообщения в таблицу Django
- Когда оба видят, что оба пользователя покинули комнату, он удаляет запись.
ejabberd или openfire будет XMPP-сервером. Apache - это веб-сервер, который запускает mod_wsgi для обслуживания Django и mod_proxy для передачи запросов XMPP-over-BOSh на сервер XMPP.
Это звучит как хорошо делать это? Какие-либо предложения? Я беспокоюсь о нагрузке на систему Django.
(Это долго. Извини.)
Метод с использованием Presence Stanzas:
На стороне клиента я использую библиотеку Strophe JS, которая поддерживает присутствие, и я добавил методы обратного вызова. Я могу использовать ejabberd или openfire в качестве моего XMPP-сервера. На сервере XMPP много посетителей - некоторые с сайта A, а некоторые с сайта B, но все они подключены к одному и тому же серверу XMPP. Когда посетитель посещает сайт, он подключается к серверу XMPP как <visitor_id>_<site_id>@demo.com
и каждый попадает в комнату под названием <visitor_id>@conference.demo.com
, Персонал отдела продаж / поддержки также подключен к серверу XMPP, так как <supportsale_id>_<site_id>@demo.com
, Они не связаны ни с одной из комнат чата. У них нет ни одного посетителя в их списке.
Хороший способ показать, что пользователь подключился к сайту, - передать раздел о присутствии сотрудникам отдела продаж / поддержки. Только посетители и сотрудники отдела продаж / поддержки с одного сайта общаются друг с другом, и поэтому у меня есть <site_id>
в имени пользователя, чтобы показать, какому сайту принадлежит это лицо.
Кажется, что вы не можете подписаться на разделы присутствия для пользователя, если у вас его нет в списке. (Вполне логично). Можно ли автоматически добавлять каждого нового пользователя сайта, подключенного к системе, в список сотрудников отдела продаж / поддержки этого сайта? Не будет ли это автоматически сигнализировать о присутствии сотрудникам отдела продаж / поддержки? Как я могу реализовать это - любая помощь?
3 ответа
Я написал именно это. Он называется Seshat и использует бот-брокера между веб-сайтом и сервером Jabber (я использую ejabberd). Сейчас он находится в бета-версии, главным образом потому, что он не был тщательно протестирован за пределами моей компании.
Примечание: хотя README специально упоминает веб-инфраструктуру Pyramid, базовая система будет работать так же хорошо с Django, TurboGears или системой командной строки. Просто я только упаковываю пример кода, показывающего, как интегрировать его с Pyramid.
Сешат активно развивается. Если у вас есть какие-либо пожелания, дайте мне знать.:-)
Я не уверен, что вам нужно использовать MUC для реализации этого. Ваш бот может поддерживать свой собственный узел pubsub, на который он подписан. Когда новый пользователь начинает печатать, он может отправить уведомление узлу pubsub, которое затем увидит бот. Оттуда бот может уведомить службу поддержки через XMPP, что устраняет необходимость длительного опроса таблицы базы данных. Затем специалист службы поддержки может начать стандартный сеанс чата с конечным пользователем. Кроме того, их присутствие может быть установлено на "na", чтобы показать, что они находятся в сеансе с пользователем.
Я думаю, что лучше использовать строфы присутствия, чтобы "сигнализировать" о любой (не) активности. В базе данных нужно хранить только постоянные данные, необходимые для дальнейшего анализа. В противном случае, я думаю, вы отлично проведете время, кодируя приложение:).
РЕДАКТИРОВАТЬ:
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), которая будет обрабатывать принятые разделы сообщений.