1. 序章

XMPP は、リッチで複雑なインスタントメッセージングプロトコルです。

このチュートリアルでは、独自のクライアントを最初から作成する代わりに、Javaで作成されたモジュール式のポータブルオープンソースXMPPクライアントであるSmackを見ていきます。我ら。

2. 依存関係

Smackは、柔軟性を高めるためにいくつかのモジュールとして編成されています。そのため、必要な機能を簡単に含めることができます。

これらのいくつかは次のとおりです。

  • XMPPoverTCPモジュール
  • XMPPStandardsFoundationによって定義された拡張機能の多くをサポートするモジュール
  • レガシー拡張機能のサポート
  • デバッグするモジュール

サポートされているすべてのモジュールは、XMPPのドキュメントにあります。

ただし、このチュートリアルでは、 tcp im 拡張機能、およびjava7モジュールを使用します。

<dependency>
    <groupId>org.igniterealtime.smack</groupId>
    <artifactId>smack-tcp</artifactId>
</dependency>
<dependency>
    <groupId>org.igniterealtime.smack</groupId>
    <artifactId>smack-im</artifactId>
</dependency>
<dependency>
    <groupId>org.igniterealtime.smack</groupId>
    <artifactId>smack-extensions</artifactId>
</dependency>
<dependency>
    <groupId>org.igniterealtime.smack</groupId>
    <artifactId>smack-java7</artifactId>
</dependency>

最新バージョンは、 MavenCentralにあります。

3. 設定

クライアントをテストするには、XMPPサーバーが必要です。 そのために、 javer.hot-chilli.net にアカウントを作成します。これは、すべての人に無料のJabber/XMPPサービスです。

その後、接続のパラメータを設定するビルダーを提供するXMPPTCPConnectionConfigurationクラスを使用してSmackを構成できます。

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

Builderを使用すると、接続を実行するために必要な基本情報を設定できます。 必要に応じて、ポート、SSLプロトコル、タイムアウトなどの他のパラメータを設定することもできます。

4. 繋がり

接続の確立は、XMPPTCPConnectionクラスを使用して簡単に実行できます。

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

このクラスには、以前に作成された構成を受け入れるコンストラクターが含まれています。 また、サーバーに接続してログインするためのメソッドも提供します。

接続が確立されると、次のセクションで説明するチャットなどのSmackの機能を使用できます。

接続が突然中断された場合、デフォルトでは、Smackは再接続を試みます。

ReconnectionManager は、サーバーへの再接続をすぐに試行し、連続する再接続が失敗し続けるため、試行間の遅延を増やします。

5. チャット

ライブラリの主な機能の1つは、チャットのサポートです。

Chat クラスを使用すると、2人のユーザー間でメッセージの新しいスレッドを作成できます。

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

Chat を構築するために、 ChatManager を使用し、明らかに、誰とチャットするかを指定したことに注意してください。 後者は、 EntityBareJid オブジェクトを使用して実現しました。このオブジェクトは、ローカル部分( baeldung2 で構成されるXMPPアドレス(別名JID)をラップします。 ])およびドメイン部分( 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は、エンドツーエンドのユーザーチャットだけでなく、部屋を使用したグループチャットのサポートも提供します。

部屋にはインスタントルームとリザーブルームの2種類があります。

インスタントルームはすぐにアクセスでき、デフォルトの構成に基づいて自動的に作成されます。 一方、予約済みの部屋は、誰もが入室できるようになる前に、部屋の所有者が手動で構成します。

MultiUserChatManagerを使用してインスタントルームを作成する方法を見てみましょう。

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

同様の方法で、予約済みの部屋を作成できます。

Set<Jid> owners = JidUtil.jidSetFrom(
  new String[] { "[email protected]", "[email protected]" });

muc.create(room)
  .getConfigFormManger()
  .setRoomOwners(owners)
  .submitConfigurationForm();

6. 名簿

Smackが提供するもう1つの機能は、他のユーザーの存在を追跡する可能性です。

Roster.getInstanceFor()を使用すると、 Rosterインスタンスを取得できます。

Roster roster = Roster.getInstanceFor(connection);

名簿は、ユーザーを名簿エントリオブジェクトとして表す連絡先リストであり、ユーザーをグループに編成できます。

getEntries()メソッドを使用して、名簿のすべてのエントリを印刷できます。

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

さらに、 RosterListener:を使用して、エントリとプレゼンスデータの変更をリッスンできます。

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

また、承認されたユーザーのみが名簿にサブスクライブできるようにすることで、ユーザーのプライバシーを保護する方法も提供します。 そうするために、Smackは権限ベースのモデルを実装します。

Roster.setSubscriptionMode()メソッドを使用してプレゼンスサブスクリプション要求を処理するには、次の3つの方法があります。

  • Roster.SubscriptionMode.accept_all –すべてのサブスクリプションリクエストを受け入れる
  • Roster.SubscriptionMode.reject_all –すべてのサブスクリプションリクエストを拒否します
  • Roster.SubscriptionMode.manual –プレゼンスサブスクリプションリクエストを手動で処理する

サブスクリプションリクエストを手動で処理する場合は、 StanzaListener (次のセクションで説明)を登録し、Presence.Type.subscribeタイプのパケットを処理する必要があります。

7. スタンザ

チャットに加えて、Smackはスタンザを送信して着信をリッスンするための柔軟なフレームワークを提供します。

明確にするために、スタンザはXMPPでの意味の個別の意味単位です。 これは、XMLストリームを介して1つのエンティティから別のエンティティに送信される構造化された情報です。

send()メソッドを使用して、接続を介してスタンザを送信できます。

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

上記の例では、名簿をサブスクライブするためにPresenceスタンザを送信しました。

一方、着信スタンザを処理するために、ライブラリは2つの構成を提供します。

  • StanzaCollector 
  • StanzaListener

特に、 StanzaCollectorでは、新しいスタンザを同期的に待機できます

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

StanzaListenerは、着信スタンザを非同期的に通知するためのインターフェースです

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

7.1. フィルタ

さらに、ライブラリには、着信スタンザを処理するための組み込みのフィルターセットが用意されています。

StanzaTypeFilter を使用してタイプで、または StanzaIdFilter:を使用してIDでスタンザをフィルタリングできます。

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

または、特定のアドレスで識別します。

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で入手できます。