Работа с XMPP протоколом с использованием PHP

2012-12-21
На сайте подробно рассказывается принцип работы xmpp протокола. Здесь будет приведен пример работы с jabber сервером с использованием библиотеки XMPPHP, а также несколько методов, отсутствующих в данной библиотеке и позволяющих делать следующее
  • удаление пользователя с jabber сервера
  • добавление/удаление в список контактов
Будем использовать тот же хост, который испльзовался нами при конфигурировании Установка соединения с сервером выполняется следующим образом

include "XMPPHP/XMPP.php";
try {
    $conn = new XMPPHP_XMPP('foodomain.com', 5222, 'admin', 'adminpass');
    $conn->autoSubscribe();
    $conn->connect();
    $conn->processUntil('session_start');
    if ($conn->isDisconnected()) {
        echo "can't connect to jabber server";
    }
} catch (Exception $e) {
    echo $e->getMessage();
}

здесь после создания объекта $conn вызывается метод autoSubscribe(), который указывает на то, что при соединении с сервером, стаутус текущего пользователя необходимо установить в значение "активный". Таким образом впоследствии, после соединения с сервером, не будет необходимости вызывать метод presence(), служащий той же цели.
Теперь можно получить список контактов данного пользователя

$conn->getRoster();
$conn->processUntil('get_roster');

Отправить сообщение

$conn->message('user@foodomain.com', 'message content', 'chat');

здесь chat - это тип сообщения. Всегод xmpp протокол поддерживает следующие типы
  • chat - чат-сообщение(используется по-умолчанию). Такие сообщения обычно открываются клиентами в виде быстрой беседы — чата
  • normal - Обычное сообщение, чем-то сходное с письмом на E-mail. Обычно клиентами оно открывается в отдельном окне
  • groupchat - сообщение специального типа, рассылаемое сервером сразу нескольким клиентам, находящимся в одной конференции
  • headline - cпециальный тип сообщений, применяемый для рассылок заголовков новостей, включающих в себя, собственно, заголовок, краткое описание новости (тело сообщения), ссылку(URL) на новость. Ссылок может не быть совсем, их может быть несколько. Примером такого сообщения может служить RSS-транспорты
  • error - сообщение об ошибке, отображается в окне чата в особым образом отформатированном виде
После того как все операции с jabber сервером выполнены отключиться от сервера можно командой

$conn->disconnect();

Рассмотрим еще несколько основных команд для работы с jabber сервером.
Зарегистрируем нового пользователя

$conn->register('newuser@foodomain.com', 'newuserpass');

Но вот для удаления пользователя с сервера в XMPPHP библиотеке отсутствует метод. Поэтому в класс XMPPHP_XMPP добавляем следующий код

/**
 * Cancel existing registration (remove user from chat)
 */
public function unregister(){
    $id = 'uregueo_' . $this->getID();
    $xml = "<iq type='set' id='$id'>
                <query xmlns='jabber:iq:register'>
                    <remove />
                </query>
            </iq>";
    $this->addIdHandler($id, 'unregister_user_handler');
    $this->send($xml);
}
 /**
 * @param XML Object $xml
 */
protected function unregister_user_handler($xml) {
    $this->event('contact_unregistered');
}

вызов будет выгдядеть следующим образом

$conn->unregister();
$conn->processUntil('contact_unregistered');

Теперь добавим методы для добавления/удаления пользователя в адресный список другого пользователя

/**
 * Add contact to your roster
 *
 * @param string $jid, full JID
 * @param string $name, nickname
 * @param array $groups
 * @return
 */
public function add_roster($jid, $name = '', $groups = array()) {
    // return if there is no jid specified
    if (!$jid) { return; }
    // set name to the jid if none is specified
    if (!$name) { $name = $jid; }
    $id = $this->getID();
    $xml = "<iq from='{$this->fulljid}' type='set' id='$id'>";
    $xml .= "<query xmlns='jabber:iq:roster'>";
    $xml .= "<item jid='$jid' name='$name'>";
    foreach ($groups as $group) {
        $xml .= "<group>$group</group>";
    }
    $xml .= "</item>";
    $xml .= "</query>";
    $xml .= "</iq>";
    $this->addIdHandler($id, 'add_roster_handler');
    $this->send($xml);
}
 /**
 * @param XML Object $xml
 */
protected function add_roster_handler($xml) {
    // do anything you wish here
    $this->event('roster_added');
}
 /**
 * Contact you wish to remove from your roster
 *
 * @param string $jid, full JID
 */
public function delete_roster($jid) {
    $id = $this->getID();
    $xml = "<iq type='set' id='$id'>";
    $xml .= "<query xmlns='jabber:iq:roster'>";
    $xml .= "<item jid='$jid' subscription='remove' />";
    $xml .= "</query>";
    $xml .= "</iq>";
    $this->addIdHandler($id, 'delete_roster_handler');
    $this->send($xml);
}
 /**
 * @param XML Object $xml
 */
protected function delete_roster_handler($xml) {
    // do any handling you wish here
    $this->event('roster_removed');

Удаление пользователя из списка контактов аналогично.