Pull to refresh

GAE XMPP (Java API) — Жаббер в своем приложении

Reading time4 min
Views8.1K
Пока у Гугла данный раздел только на английском, я делюсь своим знакомством с данной службой.

image

Служба XMPP позволяют GAE-приложениям отправлять и принимать жаббер-сообщения.
XMPP – открытый протокол обмена мгновенными сообщениями, на основе XML, так же известный как Jabber. Именно он уже используется в Google Talk.

API скрывают весь механизм работы с протоколом. Разработчик получает очень высокоуровневые методы, что упрощают разработку, но в то же время очень ограничивают возможности.
Если просмотреть джавадок по XMPP API, то видно, что реализован только самый необходимый минимум.

Отправляем сообщение

Вся работа с протоколом осуществляется через экземпляр объекта com.google.appengine.api.xmpp.XMPPService, который содержит все необходимые методы. Пример отправки сообщения:

import com.google.appengine.api.xmpp.JID;
import com.google.appengine.api.xmpp.Message;
import com.google.appengine.api.xmpp.MessageBuilder;
import com.google.appengine.api.xmpp.SendResponse;
import com.google.appengine.api.xmpp.XMPPService;
import com.google.appengine.api.xmpp.XMPPServiceFactory;

// ...
        JID jid = new JID("example@gmail.com");
        String msgBody = "Hello World from GAE";
        Message msg = new MessageBuilder()
            .withRecipientJids(jid)
            .withBody(msgBody)
            .build();
                
        boolean messageSent = false;
        XMPPService xmpp = XMPPServiceFactory.getXMPPService();
        if (xmpp.getPresence(jid).isAvailable()) {
            SendResponse status = xmpp.sendMessage(msg);
            messageSent = (status.getStatusMap().get(jid) == SendResponse.Status.SUCCESS);
        }

        if (!messageSent) {
            // Send an email message instead...
        }


Приложению доступны адреса – JID-ы: app-id@appspot.com (по умолчанию) и anything@app-id.appspotchat.com. Если версия приложения не дефаултная, то используется (принудительно!) — anything@version.latest.app-id.appspotchat.com. Пока служба не позволяет использовать в JID свое доменное имя, используемое для приложения.

Адресатом может быть любой действительный JID (не обязательно Google Talk пользователь).

Для обмена сообщениями, приложение и адресат должны быть авторизованы друг у друга – обменяться инвайтами, как в любом мессенджере. Можно послать приглашение приложению, тогда служба автоматически его примет и отправит ответное приглашение. Либо, отправить приглашение из приложения:

xmpp.sendInvitation(jid);


К сожалению, нет возможности проверить авторизован ли JID. Можно только узнать статус, и то с большими ограничениями:

xmpp.getPresence(fromJid).isAvailable();


Результат будет положительным, только если собеседник в он-лайне, использует Google Talk и авторизован. Определить дополнительные статусы невозможно.

Нет возможности работы со списком контактов. И нет возможности залогиниться обычным джаббер клиентом под аккаунтом приложения, для ручного редактирования списка контактов.

Принимаем сообщение

Для получения сообщений необходимо «включить» службу, добавив следующие строчки в конфигурационный файл приложения appengine-web.xml:

<inbound-services>
    <service>xmpp_message</service>
</inbound-services>


Теперь, при получении сообщения на один из адресов, которые принадлежат приложению, GAE выполняет POST-запрос на URL /_ah/xmpp/message/chat/. В запросе содержится само сообщение, JID-ы отправителя и получателя (на какой именно адрес было послано) и stanza – полный формат XMPP сообщения в XML.

GAE предоставляет доступ к URL /_ah/xmpp/message/chat/ только пользователям с ролью администратора, поэтому для внешнего мира он недоступен.

Остается написать сам сервлет:

import java.io.IOException;
import javax.servlet.http.*;
import com.google.appengine.api.xmpp.JID;
import com.google.appengine.api.xmpp.Message;
import com.google.appengine.api.xmpp.XMPPService;
import com.google.appengine.api.xmpp.XMPPServiceFactory;

@SuppressWarnings("serial")
public class XMPPReceiverServlet extends HttpServlet {
    public void doPost(HttpServletRequest req, HttpServletResponse res)
          throws IOException {
        XMPPService xmpp = XMPPServiceFactory.getXMPPService();
        Message message = xmpp.parseMessage(req);

        JID fromJid = message.getFromJid();
        String body = message.getBody();
        // ...
    }
}


Как видим, в API уже есть готовый парсер для обработки таких запросов.

Осталось только, замапить сервлет на данный URL (web.xml):

<web-app>
…
<servlet>
    <servlet-name>xmppreceiver</servlet-name>
    <servlet-class>XMPPReceiverServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>xmppreceiver</servlet-name>
    <url-pattern>/_ah/xmpp/message/chat/</url-pattern>
 </servlet-mapping>
…
<web-app>


XMPP служба имеет свои квоты на количество отправленных сообщений, объем отправленных сообщений, а так же на количество API-вызовов самой службы. Входящие сообщения так же тарифицируются, как входящий HTTP-запрос. Квоты

В заключение

На деле XMPP службу можно использовать для отправления различных админских уведомлений, особенно удобно на мобильные устройства. Нет никакой защиты от злоумышленного расхода квот, при желании злоумышленник может исчерпать все квоты.

Кому интересно, предлагаю небольшой пример работы службы: http://samples-gae.appspot.com/samples/xmpp.html

Раздел в документации (на английском): XMPP Java API Overview

Огромное Спасибо garbuz за инвайт!

Добавлено 14-02-2010:

Вышел новый релиз GAE SDK 1.4.2, со второй версией XMPP, много нового.
Tags:
Hubs:
Total votes 51: ↑45 and ↓6+39
Comments35

Articles