Ръководство за XMPP Smack Client

1. Въведение

XMPP е богат и сложен протокол за незабавни съобщения.

Вместо да пишем собствения си клиент от нулата, в този урок ще разгледаме Smack, модулен и преносим XMPP клиент с отворен код, написан на Java, който е направил голяма част от тежката работа за нас.

2. Зависимости

Smack е организиран като няколко модула, за да осигури по-голяма гъвкавост , така че лесно можем да включим функциите, от които се нуждаем.

Някои от тях включват:

  • XMPP през TCP модул
  • Модул за поддържане на много от разширенията, дефинирани от фондацията за стандарти XMPP
  • Поддръжка на наследени разширения
  • Модул за отстраняване на грешки

Можем да намерим всички поддържани модули в документацията на XMPP.

В този урок обаче ние просто ще използваме модулите tcp , im , extensions и java7 :

 org.igniterealtime.smack smack-tcp   org.igniterealtime.smack smack-im   org.igniterealtime.smack smack-extensions   org.igniterealtime.smack smack-java7 

Най-новите версии могат да бъдат намерени в Maven Central.

3. Настройка

За да тестваме клиента, ще ни трябва XMPP сървър. За целта ще създадем акаунт в jabber.hot-chilli.net, безплатна услуга Jabber / XMPP за всички.

След това можем да конфигурираме Smack, като използваме класа XMPPTCPConnectionConfiguration, който осигурява конструктор за настройка на параметрите на връзката:

XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder() .setUsernameAndPassword("baeldung","baeldung") .setXmppDomain("jabb3r.org") .setHost("jabb3r.org") .build();

Конструкторът ни позволява да зададем основната информация, необходима за осъществяване на връзка . Ако е необходимо, можем да зададем и други параметри като порт, SSL протоколи и изчаквания.

4. Връзка

Осъществяването на връзка се постига просто с помощта на класа XMPPTCPConnection :

AbstractXMPPConnection connection = new XMPPTCPConnection(config); connection.connect(); //Establishes a connection to the server connection.login(); //Logs in 

Класът съдържа конструктор, който приема предварително изградената конфигурация. Той също така предоставя методи за свързване със сървъра и влизане.

След като се установи връзка, можем да използваме функциите на Smack , като чата , които ще опишем в следващия раздел.

В случай, че връзката внезапно е била прекъсната, по подразбиране Smack ще се опита да се свърже отново.

В ReconnectionManager ще се опита да се свърже отново веднага към сървъра и да се увеличи закъснението между опитите като последователни повторните продължи да бъде неуспешно.

5. Чат

Една от основните характеристики на библиотеката е - чат поддръжка.

Използването на класа Chat дава възможност да се създаде нова нишка от съобщения между двама потребители:

ChatManager chatManager = ChatManager.getInstanceFor(connection); EntityBareJid jid = JidCreate.entityBareFrom("[email protected]"); Chat chat = chatManager.chatWith(jid);

Имайте предвид, че за изграждането на чат използвахме ChatManager и очевидно посочихме с кого да разговаряме. Последното постигнахме с помощта на обекта EntityBareJid , койтообвива XMPP адрес - или JID -, съставен от локална част ( baeldung2 ) и част от домейн ( jabb3r.org ).

След това можем да изпратим съобщение, използвайки метода send () :

chat.send("Hello!");

И получавайте съобщения, като настроите слушател:

chatManager.addIncomingListener(new IncomingChatMessageListener() { @Override public void newIncomingMessage(EntityBareJid from, Message message, Chat chat) { System.out.println("New message from " + from + ": " + message.getBody()); } });

5.1. Стаи

Освен чат от край до край, Smack предоставя поддръжка за групови чатове чрез използване на стаи .

Има два вида стаи, незабавни стаи и резервирани стаи.

Незабавните стаи са на разположение за незабавен достъп и се създават автоматично въз основа на конфигурация по подразбиране. От друга страна, резервираните стаи се конфигурират ръчно от собственика на стаята, преди някой да има право да влиза.

Нека да разгледаме как да създадем незабавна стая с помощта на MultiUserChatManager :

MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(connection); MultiUserChat muc = manager.getMultiUserChat(jid); Resourcepart room = Resourcepart.from("baeldung_room"); muc.create(room).makeInstant();

По подобен начин можем да създадем запазена стая:

Set owners = JidUtil.jidSetFrom( new String[] { "[email protected]", "[email protected]" }); muc.create(room) .getConfigFormManger() .setRoomOwners(owners) .submitConfigurationForm();

6. Състав

Друга функция, която Smack предоставя, е възможността да се проследява присъствието на други потребители.

С Roster.getInstanceFor () можем да получим екземпляр на Roster :

Roster roster = Roster.getInstanceFor(connection);

В списъка е списък с контакти, която представлява потребителите като RosterEntry обекти и ни позволява да организирате потребителите в групи.

We can print all entries in the Roster using the getEntries() method:

Collection entries = roster.getEntries(); for (RosterEntry entry : entries) { System.out.println(entry); }

Moreover, it allows us to listen for changes in its entries and presence data with a RosterListener:

roster.addRosterListener(new RosterListener() { public void entriesAdded(Collection addresses) { // handle new entries } public void entriesDeleted(Collection addresses) { // handle deleted entries } public void entriesUpdated(Collection addresses) { // handle updated entries } public void presenceChanged(Presence presence) { // handle presence change } });

It also provides a way to protect user's privacy by making sure that only approved users are able to subscribe to a roster. To do so, Smack implements a permissions-based model.

There are three ways to handle presence subscription requests with the Roster.setSubscriptionMode() method:

  • Roster.SubscriptionMode.accept_all – Accept all subscription requests
  • Roster.SubscriptionMode.reject_all – Reject all subscription requests
  • Roster.SubscriptionMode.manual – Process presence subscription requests manually

If we choose to handle subscription requests manually, we'll need to register a StanzaListener (described in next section) and handle packets with the Presence.Type.subscribe type.

7. Stanza

In addition to the chat, Smack provides a flexible framework to send a stanza and listen for incoming one.

To clarify, a stanza is a discrete semantic unit of meaning in XMPP. It is structured information that is sent from one entity to another over an XML stream.

We can transmit a Stanza through a Connection using the send() method:

Stanza presence = new Presence(Presence.Type.subscribe); connection.sendStanza(presence);

In the example above, we sent a Presence stanza to subscribe to a roster.

On the other hand, to process the incoming stanzas, the library provides two constructs:

  • StanzaCollector
  • StanzaListener

In particular, StanzaCollector let us wait synchronously for new stanzas:

StanzaCollector collector = connection.createStanzaCollector(StanzaTypeFilter.MESSAGE); Stanza stanza = collector.nextResult();

While StanzaListener is an interface for asynchronously notifying us of incoming stanzas:

connection.addAsyncStanzaListener(new StanzaListener() { public void processStanza(Stanza stanza) throws SmackException.NotConnectedException,InterruptedException, SmackException.NotLoggedInException { // handle stanza } }, StanzaTypeFilter.MESSAGE);

7.1. Filters

Moreover, the library provides a built-in set of filters to process incoming stanzas.

We can filter stanza by type using StanzaTypeFilter or by ID with StanzaIdFilter:

StanzaFilter messageFilter = StanzaTypeFilter.MESSAGE; StanzaFilter idFilter = new StanzaIdFilter("123456");

Or, discerning by particular address:

StanzaFilter fromFilter = FromMatchesFilter.create(JidCreate.from("[email protected]")); StanzaFilter toFilter = ToMatchesFilter.create(JidCreate.from("[email protected]"));

И можем да използваме оператор на логически филтър ( AndFilter , OrFilter , NotFilter ), за да създадем сложни филтри:

StanzaFilter filter = new AndFilter(StanzaTypeFilter.Message, FromMatchesFilter.create("[email protected]"));

8. Заключение

В тази статия разгледахме най-полезните класове, които Smack предлага от рафта.

Научихме как да конфигурираме библиотеката, за да изпращаме и получаваме XMPP строфа.

Впоследствие научихме как да се справяме с групови чатове, използвайки функциите ChatManager и Roster .

Както обикновено, всички примерни кодове, показани в този урок, са достъпни в GitHub.