xmppクライアント・プログラミング
TRANSCRIPT
XMPP クライアント・プログラミング神戸隆行(椎路ちひろ) Twitter: @ChihiroShiiji / FB: takayuki.kando
2016/04/03 (第 13 回福岡市西区プログラム勉強会資料)
自己紹介 神戸 隆行(かんど たかゆき)、 PN. 椎路ちひろ(しいじ ちひろ) Twitter: @ChihiroShiiji / FB: takayuki.kando 出身は名古屋、趣味イラストとコスプレ 本業は九大の社会人博士課程で博士を取ろうとしながら研究開発に従事する有期雇用の勤め人@百道浜 専門は流転中:
数値解析(のプログラミング・インターフェースの改良、修論@名大)→数式処理(のプログラミング・インターフェースの改良@某 F 研) →プログラム最適化(博士課程一回目の失敗@東工大)( 2005 年に仕事を紹介され福岡へ来た)→コンパイラ開発( Redefis 、動的再構成可能プロセッサ向けコンパイラ)→ SW/HW 開発環境( IDE 上からクラウド上の開発ツールを利用できるミドルウェアPTaaS の開発) http://www.qualiarc.com/?post_type=seihin&p=202
使用プログラミング言語: 最初は FORTRAN 、大学以降は C++ と C 、今は主に Java 、他は必要に応じてボチボチ
本日は趣味と仕事で利用している XMPP のクライアント・プログラミング 幾つかのソースとサンプルを GitHub[ https://github.com/TakayukiKando/Lore ] に置いてます
2016/04/032 第 13 回福岡市西区プログラム勉強会
本日の内容
2016/04/03第 13 回福岡市西区プログラム勉強会3
準備1. XMPP サーバのインストール2. XMPP ユーザアカウントの作成3. Smack API ライブラリのインストール
サンプルプログラム "EchoBot" 話かけるとオウム返ししてきて、以降無理やり 5 分毎に時報を送ってくるやや迷惑なボット(自動クライアント) Gist "EchoBot.java":
https://gist.github.com/TakayukiKando/ca0c72a07bcdd04f7a55595895ea296d
本日のターゲット(赤破線枠内):XMPP ネットワークの構造と機能
XMPPサーバXMPPクライアント
XMPPサーバ・コンポーネントXMPPクライアントXMPPクライアントXMPPクライアント
他所のXMPPサーバ
UserA
UserB
ボット(ユーザがおらず自動応答するクライアント)
サーバに機能を追加するメッセージ等をルーティングするユーザを認証するユーザーアカウント情報を管理するユーザの連絡先リストを管理するオフライン・メッセージを保管する
実装ポリシー:クライアントは UI に専念サーバ側に様々な機能を実現することが推奨されている 2016/04/034 第 13 回福岡市西区プログラム勉強会
Openfire サーバの特徴
2016/04/03第 13 回福岡市西区プログラム勉強会6
配布元: ignite realtime 社、オープンソース 2016 年 4 月 2 日現在の最新版は 4.0.2 http://www.igniterealtime.org/projects/openfire/index.jsp
中小企業程度の規模までをターゲットとする XMPP サーバ XMPP とその拡張について一通りの機能は実装されている Web ( 9090番ポート)で設定用 GUI が提供されている
というか設定手段はそれだけなので自動化する際には難がある 詳しくは「 JMeter を Web でしか設定できないサーバの設定自動化に使う」(福岡
Java ツール勉強会資料)へ http://www.slideshare.net/takayukikando/jmeterweb
Java で書かれている Linux でもWindows でも(未確認だけど多分 Mac でも)動く Java でサーバ機能を拡張するサーバ・コンポーネント作成可能
Windows 版はインストーラ (.exe)あり .rpm(Linux) 、 .deb(Debian) 、 .dmg(Mac)もある
インストール後入力を求められること
2016/04/03第 13 回福岡市西区プログラム勉強会7
localhost の 9090 ポートに Web ブラウザでアクセスすると管理画面(初回は初期設定画面) Windows では起動ダイアログにある Launch Admin ボタンでも可
サーバ名(サーバの DNS 名) Windows環境で DNS 名割り当てなしの場合、 localhost からテストに使うだけであればはホスト名と同じにしておいても動く
以下の設定画面例は Windows でホスト名と同じ "ostrich" と設定した場合 管理者 ID とパスワード
管理者 ID ( JID の "@" の左側)とパスワードを決めておく スキップした場合はユーザ名 "admin" 、パスワード "admin" となる
RDB の指定 内蔵( Embedded )の簡易DB を使う設定もあり
今回は localhost でテストに使いたいだけなのでこちらを選択 標準的には PostgrsSQL を利用
インストーラーが入れてくれます
インストール後のログイン
2016/04/03第 13 回福岡市西区プログラム勉強会8
管理者のパスワードはインストール時に設定した物 スキップしてしまった場合
デフォルト管理者のユーザ名 "admin" 、パスワード: "admin" ユーザ作成後はそのユーザ名とパスワードでログイン可
ユーザ名は Jabbar ID の "@"より前の部分
データベース設定の確認
2016/04/03第 13 回福岡市西区プログラム勉強会10
"Database" を選ぶとこの画面になる "embedded-db" になっていれば組み込み簡易 DB が使われている
ユーザ登録前のおさらい:XMPP の ID ( Jabber ID 、 JID ) ユーザ・アカウント、ユーザが利用する個々の接続、サーバ、サーバの拡張機能といったものを一意に識別する名前
メッセージなどを配信する際に宛先として使用する 連絡先リストの識別子( ID )でもある このようにユーザはクライアントの接続毎に識別できるため複数個所からの接続が可能
一般形は: <ユーザ名>@<サービス名> /<リソース名>
例: xmpp.xgmtk.org という DNS 名の XMPP サーバ: xmpp.xgmtk.org 上記サーバのユーザ kando : [email protected] 上記ユーザ kando が使うクライアント(リソース名 client )からの接続 :
[email protected]/client 上記サーバの拡張コンポーネント chatroom : chatroom.xmpp.xgmtk.org
名称は XMPP がかつて Jabber と呼ばれていたことによる2016/04/0312 第 13 回福岡市西区プログラム勉強会
新規ユーザ作成
2016/04/03第 13 回福岡市西区プログラム勉強会13
テストに利用するアカウントを作成 少なくとも 1 つあれば主だったクライアント機能のテストはできる
が、 2 つほど作っておくと分かり易いと思うユーザ名。 Jabber ID の "@"より左側の部分。使える文字はメールのユーザ名と同じ
ニックネーム。任意の文字列。省略可。メールアドレス。省略可。パスワード。 XMPP ログイン時と WebUI のログインで共通パスワード確認。パスワードと同じ文字列。
管理権限のあるアカウントを作る時にチェック
"Create New User" を選ぶとこの画面になる
"User/Groups" の "Users" タブを選ぶとユーザ管理画面
ユーザ登録後のユーザ一覧( User Summary )
2016/04/03第 13 回福岡市西区プログラム勉強会14
テスト用のユーザの Roster (連絡先リスト)を編集して相互に連絡可能( Both )なように登録する 連絡先リストに関する操作をクライアントで行う場合は不要 今回のサンプルコードではその辺りは省いているので必要
編集するユーザのEdit アイコンをクリック
例:ユーザ emiri.k の連絡先一覧
2016/04/03第 13 回福岡市西区プログラム勉強会15
3. Edit アイコンをクリックすると表示される属性ダイアログで subscription を編集して Both にしておく
2. "Add New Item" で Rosterにエントリを追加しておく
1. "User Options" の "Roster" を選ぶとこの画面になる
※ 連絡先リストには別サーバの Jabber IDも登録されるのでサーバ名も含める
オマケ: Spark
2016/04/03第 13 回福岡市西区プログラム勉強会16
Openfire の提供元が提供する XMPP クライアント Java で書かれている 名前の似ている SparkWeb は Webページ組み込み用のクライアント
配布元: ignite realtime 社、オープンソース 2016 年 4 月 2 日現在の最新版は 2.7.6 http://www.igniterealtime.org/projects/spark/index.
jsp Windows 版はインストーラ (.exe)あり
.rpm(Linux) 、 .deb(Debian) 、 .dmg(Mac)もある クライアント・プログラミングに必須ではないがサーバの動作を確認したい時など、比較用にあると便利
クライアント用ライブラリ Smack API
2016/04/03第 13 回福岡市西区プログラム勉強会18
配布元: ignite realtime 社、オープンソース 2016 年 4 月 2 日現在の最新版は 4.1.6 http://www.igniterealtime.org/projects/smack/inde
x.jsp DL
http://www.igniterealtime.org/downloads/download-landing.jsp?file=smack/smack_4_1_6.zip
http://www.igniterealtime.org/downloads/download-landing.jsp?file=smack/smack_4_1_6.tar.gz
Java で書かれたクライアント用ライブラリ 一通りの機能は揃っている
自分で拡張機能の実装でもしない限りは、 XML パーサを呼んで XML 要素をパース&生成する必要はない Java 7 SE 以上、 Java 8 SE でも動く
Smack API のインストール
2016/04/03第 13 回福岡市西区プログラム勉強会19
環境に応じて .zip か .tar.gz ファイルをダウンロード&展開 必要な .jar ファイルにクラスパスを通す
smack-core.jar … コア部分 smack-extensions.jar …拡張部分 smack-debug.jar …デバッグ用拡張
Smack API をソースからコンパイルする場合 Gradle や Maven を依存の自動解決をしないならば Xml
Pull Parser (詳細は付録に)のインストールが必要 Xml Pull Parser: http://www.xmlpull.org/
XMPP/ Smack API プログラミングの基本
2016/04/03第 13 回福岡市西区プログラム勉強会21
XMPP のポリシ 複雑な機能はサーバ側で実装 クライアントは UI の提供に徹する
サービスの類は本当はボットとか作らずにサーバコンポーネントにするのが望ましい 今回はサンプルなので UI を省いてメッセージ処理に集中するためボットを作成
Smack API の基本 接続を表す XMPPConnection オブジェクトが中心
コネクションに紐づけられた各種マネージャを介して XMPP の実装にアクセスする 基本はリスナ登録を通じたイベント・ドリブンなプログラミング 一応、フィルタとコレクタを使って着信を待つスタイルもあります
タイムアウトが実現できるので返信を待つような場合に使われる プロトコル実装上、返信を待つ必要がある際に良く使われる
今回は利用しなかった
EchoBot
2016/04/03第 13 回福岡市西区プログラム勉強会22
仕様 自動クライアント
ログイン情報はプロパティファイル resource/echo.properties で与える
標準入力から "quit\n" が入力されると終了 ボットのプレゼンス情報(時間表示付き)を 30秒ごとに更新 メッセージを送ると同文を返信する 一度メッセージを送られるとその相手へ 5 分毎の時報を送信
ソース Gist "EchoBot.java":
https://gist.github.com/TakayukiKando/ca0c72a07bcdd04f7a55595895ea296d
EchoBot のプロジェクト構成とEchoBot クラスの構造
2016/04/03第 13 回福岡市西区プログラム勉強会24
下:プロジェクトの構成 パッケージ構造と echo.properties 、参照ライブラリに注目
右:クラスの構造
main()
2016/04/03第 13 回福岡市西区プログラム勉強会25
メインスレッドを待機させる
ログインに必要な情報を取得するメッセージ処理本体
ここではサボってますが終了前に connection の disconnect() メソッドを呼んで接続を切断しましょう
EchoBot コンストラクタ
2016/04/03第 13 回福岡市西区プログラム勉強会27
XMPPConnection クラスのオブジェクトがクライアント・プログラミングの中心 基本機能は conn.getAAAManager() 、拡張機能は XXX.getXXXManager(cconn) で各機能のマネージャーを取得してそれを操作することで実現できる マネージャーはコネクションと紐づけられているので何度取得しても基本的に同じオブジェクトが返る
保存しておかなくてもいい
接続~ログイン
デバッグモード指定(opt.)自身をチャットメッセージのリスナとして登録時報機能開始Presence更新開始
chat セッションを保持するリストnew する時に参照される
リソース名に自身のクラス名を利用(同一アドレスから一個しか接続できない)
ChatListener としてのメソッド
2016/04/03第 13 回福岡市西区プログラム勉強会28
1対 1 のチャットセッションが開始された際に呼ばれる 引数
Chat オブジェクトはセッションを表す createdLocally引数は自身が開始したセッションである時に
true 動作
自身をメッセージリスナとして Chat オブジェクトに登録 時報発信のためのリストに登録
MessageListener としてのメソッド(エコー機能の実現)
2016/04/03第 13 回福岡市西区プログラム勉強会29
セッションでメッセージが着信した際に呼ばれる 引数
Chat オブジェクトはメッセージが届いたセッションを示す Message オブジェクトはメッセージ
XMPP の Message スタンザを表すオブジェクト 送信者( From )は XMPP サーバが付けるのでクライアントによる詐称はできない
クライアントが付けて送っても上書きされる 宛先 (To) 、送信者とタイムスタンプ、本文以外に付加的なフィールドが幾つかある
スレッド識別子とかムード情報とか、言語情報とか、……、 etc.
送信者を取り出す
送信者へメッセージを送り返すgetBody() でメッセージ本文が取れるのでそれを渡してオウム返しさせている
エラーはログを吐いて黙殺
setTimeSignal()(時報機能の実現)
2016/04/03第 13 回福岡市西区プログラム勉強会30
引数 interval は時報間隔のミリ秒 EchoBot の static なタイマー( TIMER )の scheduleAtFixedRate() で開始時刻と時間間隔を指定して一定時間ごとに TimerTask を実行させる TimerTask 内では現在時刻を取得、フォーマットして
sendMessageToAll() を呼び出す
時報開始時刻の設定。切りのいい時刻になるよう、現在時刻から分、秒、ミリ秒を 0 に設定。
sendMessageToAll()(リストに記録された全セッションへの同報)
2016/04/03第 13 回福岡市西区プログラム勉強会31
ChatListener のメソッドでリストに記録しておいた全セッションへの同一メッセージの送信(同報)
setPresenceUpdater()( Presence更新機能の実現)
2016/04/03第 13 回福岡市西区プログラム勉強会32
引数 interval は Presence更新間隔のミリ秒 EchoBot の static なタイマー( TIMER )の
scheduleAtFixedRate() で開始時刻(現在)と時間間隔を指定して一定時間ごとに TimerTask を実行させる TimerTask 内では現在時刻を取得、フォーマットして
sendPresence() を呼び出す
sendPresence()( Presence の送信)
2016/04/03第 13 回福岡市西区プログラム勉強会33
引数 status は Presence に表示する任意のテキスト 現況を簡潔に表す短文
Presence は XMPP の Presence スタンザを表すオブジェクト Type は通常の状態の表示に使うのは available (接続中) , unavailable (非接続)の 2種
残りの subscribe, subscribed, unsubscribe, unsubscribed, error は連絡先リストへの登録、解除のプロトコルに利用される。 Mode は chat (会話歓迎) , available (接続している) , away (離席中) , xa(長時間の離席) , dnd ( Don't disturb.忙しい)の 5種類 Message スタンザと同じく付加的なフィールドが幾つかある
Presence スタンザは連絡先リスト全体に送られるのでできるだけ小さくするのが望ましい
まとめXMPP/ Smack API プログラミング
2016/04/03第 13 回福岡市西区プログラム勉強会34
XMPP のポリシ 複雑な機能はサーバ側で実装 クライアントは UI の提供に徹する
サービスの類は本当はボットとか作らずにサーバコンポーネントにするのが望ましい 今回はサンプルなので UI を省いてメッセージ処理に集中するためボットを作成
Smack API の基本 接続を表す XMPPConnection オブジェクトが中心
コネクションに紐づけられた各種マネージャを介して XMPP の実装にアクセスする 基本はリスナ登録を通じたイベント・ドリブンなプログラミング 一応、フィルタとコレクタを使って着信を待つスタイルもあります
タイムアウトが実現できるので返信を待つような場合に使われる プロトコル実装上、返信を待つ必要がある際に良く使われる
今回は利用しなかった
XML Pull Parser について Xml Pull Parser
http://www.xmlpull.org/ 実装例
kXML Web: http://www.kxml.org/ SourceForge(JAR ファイル):
https://sourceforge.net/projects/kxml/ MXP1 ( Smack が使っているが、ダウンロード URL がリンク切れ)
http://www.extreme.indiana.edu/xgws/xsoap/xpp/mxp1/
2016/04/0336 第 13 回福岡市西区プログラム勉強会