Guide du client XMPP Smack

1. Introduction

XMPP est un protocole de messagerie instantanée riche et complexe.

Au lieu d'écrire notre propre client à partir de zéro, dans ce tutoriel, nous allons jeter un coup d'œil à Smack, un client XMPP open source modulaire et portable écrit en Java qui a fait une grande partie du gros du travail pour nous.

2. Dépendances

Smack est organisé en plusieurs modules pour offrir plus de flexibilité , afin que nous puissions facilement inclure les fonctionnalités dont nous avons besoin.

Certains d'entre eux incluent:

  • Module XMPP sur TCP
  • Un module pour prendre en charge de nombreuses extensions définies par la XMPP Standards Foundation
  • Prise en charge des extensions héritées
  • Un module à déboguer

Nous pouvons trouver tous les modules pris en charge dans la documentation de XMPP.

Cependant, dans ce tutoriel, nous utiliserons simplement les modules tcp , im , extensions et java7 :

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

Les dernières versions sont disponibles sur Maven Central.

3. Configuration

Afin de tester le client, nous aurons besoin d'un serveur XMPP. Pour ce faire, nous allons créer un compte sur jabber.hot-chilli.net, un service Jabber / XMPP gratuit pour tout le monde.

Ensuite, nous pouvons configurer Smack à l'aide de la classe XMPPTCPConnectionConfiguration qui fournit un générateur pour configurer les paramètres de la connexion:

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

Le constructeur nous permet de définir les informations de base nécessaires pour effectuer une connexion . Si nécessaire, nous pouvons également définir d'autres paramètres tels que le port, les protocoles SSL et les délais d'expiration.

4. Connexion

L'établissement d'une connexion est simplement réalisé en utilisant la classe XMPPTCPConnection :

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

La classe contient un constructeur qui accepte la configuration précédemment construite. Il fournit également des méthodes pour se connecter au serveur et se connecter.

Une fois la connexion établie, nous pouvons utiliser les fonctionnalités de Smack , comme le chat , que nous décrirons dans la section suivante.

Dans le cas où la connexion serait soudainement interrompue, par défaut, Smack tentera de se reconnecter.

Le ReconnectionManager va essayer de se reconnecter immédiatement au serveur et augmenter le délai entre les tentatives de reconnexions successives continuent à être défaillants.

5. Chatter

L'une des principales fonctionnalités de la bibliothèque est la prise en charge du chat.

L'utilisation de la classe Chat permet de créer un nouveau fil de messages entre deux utilisateurs:

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

Notez que, pour créer un Chat, nous avons utilisé un ChatManager et, évidemment, spécifié avec qui discuter. Nous avons réalisé ce dernier en utilisant l' objet EntityBareJid , quiencapsule une adresse XMPP - c'est-à-dire un JID - composée d'une partie locale ( baeldung2 ) et d'une partie domaine ( jabb3r.org ).

Après cela, nous pouvons envoyer un message en utilisant la méthode send () :

chat.send("Hello!");

Et recevez des messages en définissant un auditeur:

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. Pièces

En plus du chat utilisateur de bout en bout, Smack prend en charge les discussions de groupe via l'utilisation de salles .

Il existe deux types de chambres, les chambres instantanées et les chambres réservées.

Les salles instantanées sont disponibles pour un accès immédiat et sont automatiquement créées en fonction d'une configuration par défaut. D'autre part, les salles réservées sont configurées manuellement par le propriétaire de la salle avant que quiconque ne soit autorisé à entrer.

Voyons comment créer une salle instantanée à l'aide de MultiUserChatManager :

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

De la même manière, nous pouvons créer une salle réservée:

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

6. Liste

Une autre fonctionnalité fournie par Smack est la possibilité de suivre la présence d'autres utilisateurs.

Avec Roster.getInstanceFor (), nous pouvons obtenir une instance Roster :

Roster roster = Roster.getInstanceFor(connection);

Le Roster est une liste de contacts qui représente les utilisateurs en tant qu'objets RosterEntry et nous permet d'organiser les utilisateurs en groupes.

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]"));

Et nous pouvons utiliser l'opérateur de filtre logique ( AndFilter , OrFilter , NotFilter ) pour créer des filtres complexes:

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

8. Conclusion

Dans cet article, nous avons couvert les classes les plus utiles que Smack propose dans le commerce.

Nous avons appris à configurer la bibliothèque afin d'envoyer et de recevoir la strophe XMPP.

Par la suite, nous avons appris à gérer les discussions de groupe à l'aide des fonctionnalités ChatManager et Roster .

Comme d'habitude, tous les exemples de code présentés dans ce didacticiel sont disponibles à l'adresse over sur GitHub.