мы работаем над приложением для обмена мгновенными сообщениями на основе XMPP, обрабатывающего постоянные группы только для членов, используя XEP-0045 и MucSub. У нас есть некоторые проблемы с заполненностью комнаты, и мы не нашли способа позволить пользователям покинуть комнату навсегда: мы пробовали несколько подходов, и ни один из них не привел к успешному поведению.
Поведение, которое мы ищем, очень похоже на WhatsApp и другие подобные мобильные приложения.
Первое, о чем мы должны были подумать, это: каких пользователей мы считаем участниками?
Мы можем использовать следующие параметры:
- принадлежность
- Роль
- Подписка
Чтобы считать это рабочим решением, нам нужно следующее:
- Все стандартные и очевидные возможности групповых бесед
- Участники могут присоединяться и выходить из группы
- Если участник покидает группу, он не может вернуться без приглашения
- Участники могут видеть список участников и их привилегии
- Членство не должно зависеть от статуса подключения участника
- Список участников и привилегии должны быть постоянными при перезагрузке сервера.
Наша тестовая среда:
- Ejabberd 19.09 с включенным mucsub
- БД PostgreSQL
Мы исследовали следующие подходы:
Подход 1:
Мы можем использовать аффилиацию, чтобы определить, является ли пользователь участником, и считать его неучастником, если аффилиация отсутствует, изгой или не аффилирован.
Кого мы считаем участником:
- Принадлежность: член (или владелец или администратор)
- Роль: любая
- Подписка: любая
Как выйти из комнаты:
а. Отправка присутствия недоступна
<presence to='[email protected]/test2' from='[email protected]' type='unavailable'>
<status>leave</status>
</presence>
б. изменение собственной принадлежности
<iq from='[email protected]/app'
id='1234'
to='[email protected]'
type='set'>
<query xmlns='http://jabber.org/protocol/muc#admin'>
<item affiliation='none' jid='[email protected]'/>
</query>
</iq>
Новые атрибуты бывших участников:
- Принадлежность: нет (или изгой, если пользователь был забанен)
- Роль: любая
- Подписка: любая (скорее пользователь будет отписан, но этот параметр не проверяется для определения участников)
Проблемы:
- Отправка сведений о недоступности не влияет на принадлежность. (Нигде не отражается в БД)
- Отправка сообщения о недоступности иногда не получает ответа от сервера (связанная проблема открыта здесь: Ejabberd MucSub: когда участник отправляет сообщение о недоступности, служба не отвечает)
- Установка принадлежности для себя не работает (согласно спецификациям: только администраторы могут изменять принадлежность)
Подход 2:
Мы можем использовать статус подписки, чтобы определить, является ли пользователь участником, и считать его неучастником, когда он отказывается от подписки.
Кого мы считаем участником:
- Принадлежность: член (или владелец или администратор)
- Роль: любая
- Подписка: подписан на все виды событий
Как выйти из комнаты:
- Пользователь покинет комнату, отписавшись.
<iq from='[email protected]'
to='[email protected]'
type='set'
id='12345'>
<unsubscribe xmlns='urn:xmpp:mucsub:0' />
</iq>
Новые атрибуты бывших участников:
- Принадлежность: член (или владелец или администратор)
- Роль: любая
- Подписка: не подписана
Проблемы:
- Бывший участник может снова присоединиться к подписке без приглашения, и использование этого подхода приведет к тому, что он снова будет считаться участником (без приглашения).