オープンソースのWAMPルーターcrossbar.ioのインストール方法とサンプル設定、WAMPクライアントの動かし方をご紹介します。
crossbar.ioの公式サイト上にもドキュメントはひと通り揃っているのですが、プログラムのアップデートに対してドキュメントの更新が追いついていません。現状Get Startedですら書かれている通り実行できない状況です。せっかくWAMPに興味を持った人がこんなところで躓いて諦めてしまうというのはあまりにも残念なので、とりあえず最新のプログラムを使ってサンプルを動かすところまでをご紹介します。
なおcrossbar.ioというのはソフトウェアの名前であると同時にそれを作ってる会社の名前でもあります。まぎらわしいので以下ソフトの方をcrossbar、会社の方をcrossbar.ioと表記します。
「いったいWAMPって何なの?」という人はこちらに簡単な説明を置いておきましたので参考にしてください。
crossbarのインストール
crossbarには各プラットフォーム用の公式dockerイメージが用意されており、プロダクション環境ではそれらを使うことが強く推奨されていますが、起動オプションを自由に変更できないため開発用途には向きません。以下に紹介するのは開発用の環境構築手順です。
なおcrossbarはPythonで書かれています。Pythonはasync/await構文をサポートした3.5以降のバージョンを使用してください。また解説で使用しているcrossbarのバージョンは18.7.2です。
Linux (UbuntuおよびRaspbian)
Ubuntu、Raspbian何れの場合も同じ手順でインストール可能です。事前にCコンパイラやヘッダファイルをインストール、venvでPythonの仮想環境を有効にした後、pipでcrossbarをインストールします。
$ sudo apt-get install build-essential python3-dev
$ mkdir crossbar
$ cd crossbar/
$ python3 -m venv venv
$ source venv/bin/activate
$ pip install wheel
$ pip install crossbar
Windows
crossbarが依存するパッケージのひとつTwistedは、Python 3.7.0との組み合わせでpipインストールするとエラーが発生してしまいます。とりあえずcrossbarを動かすにはPython 3.6.xを使ってください。また、twistedはcrossbarをインストールする前にwindows_platformを指定してインストールしておきます。
mkdir crossbar
cd crossbar
python -m venv venv
venv\Scripts\activate.bat
pip install Twisted[windows_platform]
pip install crossbar
Mac
crossbarのバージョン18.7.xはMac上で動かすとpsutilまわりでエラーが発生するのですが、対応されるまでしばらく時間がかかりそうな様子です。パッチを当てたforkをgithubで公開している人がいるので、これを利用してインストールします。
$ mkdir crossbar
$ cd crossbar/
$ python3 -m venv venv
$ source venv/bin/activate
$ pip install wheel
$ pip install "git+https://github.com/jaimewyant/crossbar.git"
動作確認 (各プラットフォーム共通)
crossbar version
を実行します。以下のようなメッセージが表示されたらインストールは完了です。
crossbar version
:::::::::::::::::
::::: _____ __
::::: : ::::: / ___/____ ___ ___ ___ / / ___ _ ____
::::::: ::::::: / /__ / __// _ \ (_-< (_-< / _ \/ _ `// __/
::::: : ::::: \___//_/ \___//___//___//_.__/\_,_//_/
:::::
::::::::::::::::: Crossbar v18.7.1
Copyright (c) 2013-2018 Crossbar.io Technologies GmbH, licensed under AGPL 3.0.
Crossbar.io : 18.7.1
Autobahn : 18.8.2
Twisted : 18.7.0-KQueueReactor
LMDB : 0.94/lmdb-0.9.22
Python : 3.7.0/CPython
Frozen executable : no
Operating system : Darwin-17.7.0-x86_64-i386-64bit
Host machine : x86_64
Release key : RWS9T4NltFjmKSMbEtETnOMxRjLhOEZ6e80T5MYzTTh/+NP9Jk20sJmA
テスト用のディレクトリを作成してcrossbar init
を実行してください。必要なサブディレクトリと設定ファイルの雛形が作成されます。.crossbar/config.json
がcrossbarのノード設定ファイルです。
$ mkdir testnode
$ cd testnode
$ crossbar init
Initializing node in directory '/Users/yasusii/crossbar/testnode'
Using template from '/Users/yasusii/crossbar/venv/lib/python3.7/site-packages/crossbar/node/templates/default'
Creating directory /Users/yasusii/crossbar/testnode/.crossbar
Creating directory /Users/yasusii/crossbar/testnode/web
Creating file /Users/yasusii/crossbar/testnode/README.md
Creating file /Users/yasusii/crossbar/testnode/.crossbar/config.json
Creating file /Users/yasusii/crossbar/testnode/web/README.md
Application template initialized
To start your node, run 'crossbar start --cbdir /Users/yasusii/crossbar/testnode/.crossbar'
続いてcrossbar start
を実行してノードを立ち上げます。オプション--cbdir
には設定ファイルが置かれた.crossbar
ディレクトリを指定します。このオプションが省略された場合はカレントディレクトリ下に.crossbar
があるものして動作します。
$ crossbar start --cbdir=./.crossbar
2018-09-02T22:15:24+0900 [Controller 1495]
2018-09-02T22:15:24+0900 [Controller 1495] :::::::::::::::::
2018-09-02T22:15:24+0900 [Controller 1495] ::::: _____ __
2018-09-02T22:15:24+0900 [Controller 1495] ::::: : ::::: / ___/____ ___ ___ ___ / / ___ _ ____
2018-09-02T22:15:24+0900 [Controller 1495] ::::::: ::::::: / /__ / __// _ \ (_-< (_-< / _ \/ _ `// __/
2018-09-02T22:15:24+0900 [Controller 1495] ::::: : ::::: \___//_/ \___//___//___//_.__/\_,_//_/
2018-09-02T22:15:24+0900 [Controller 1495] :::::
2018-09-02T22:15:24+0900 [Controller 1495] ::::::::::::::::: Crossbar v18.7.1
2018-09-02T22:15:24+0900 [Controller 1495]
2018-09-02T22:15:24+0900 [Controller 1495] Copyright (c) 2013-2018 Crossbar.io Technologies GmbH, licensed under AGPL 3.0.
2018-09-02T22:15:24+0900 [Controller 1495]
2018-09-02T22:15:24+0900 [Controller 1495] Initializing <class 'crossbar.personality.Personality'> node from node directory "/Users/yasusii/crossbar/testnode/.crossbar"
2018-09-02T22:15:24+0900 [Controller 1495] Node key loaded from "/Users/yasusii/crossbar/testnode/.crossbar/key.priv"
2018-09-02T22:15:24+0900 [Controller 1495] Node configuration loaded from "/Users/yasusii/crossbar/testnode/.crossbar/config.json"
2018-09-02T22:15:24+0900 [Controller 1495] Entering event reactor ...
2018-09-02T22:15:24+0900 [Controller 1495] Starting standalone node
2018-09-02T22:15:24+0900 [Controller 1495] Node ID "yasushi-no-mac-mini.local" set from hostname
2018-09-02T22:15:24+0900 [Controller 1495] No extra node router roles
2018-09-02T22:15:24+0900 [Controller 1495] RouterServiceAgent ready (realm_name="crossbar", on_ready=None)
2018-09-02T22:15:24+0900 [Controller 1495] Registered 21 procedures
2018-09-02T22:15:24+0900 [Controller 1495] Signal handler installed on process 1495 thread 140735583114112
2018-09-02T22:15:24+0900 [Controller 1495] Using default node shutdown triggers ['shutdown_on_worker_exit']
2018-09-02T22:15:24+0900 [Controller 1495] Booting node
2018-09-02T22:15:24+0900 [Controller 1495] Configuring node from local configuration
2018-09-02T22:15:24+0900 [Controller 1495] Starting 1 workers ...
2018-09-02T22:15:24+0900 [Controller 1495] Starting router worker "worker-001"
2018-09-02T22:15:24+0900 [Controller 1495] Starting new managed worker process for Router worker "worker-001"
2018-09-02T22:15:25+0900 [Router 1498] Starting worker "worker-001" for node "yasushi-no-mac-mini.local" with personality "standalone"
2018-09-02T22:15:25+0900 [Router 1498] Running as PID 1498 on CPython-KQueueReactor
2018-09-02T22:15:25+0900 [Router 1498] Entering event reactor ...
2018-09-02T22:15:25+0900 [Router 1498] Router worker session for "worker-001" joined realm "crossbar" on node router
2018-09-02T22:15:25+0900 [Router 1498] Registered 41 procedures
2018-09-02T22:15:25+0900 [Router 1498] Router worker session for "worker-001" ready
2018-09-02T22:15:25+0900 [Controller 1495] Router worker "worker-001" process 1498 started
2018-09-02T22:15:25+0900 [Router 1498] Starting router realm "realm-001"
2018-09-02T22:15:25+0900 [Router 1498] RouterServiceAgent ready (realm_name="realm1", on_ready=<Deferred at 0x107cea7b8>)
2018-09-02T22:15:25+0900 [Router 1498] Realm "realm-001" (name="realm1") started
2018-09-02T22:15:25+0900 [Controller 1495] Router "worker-001": realm 'realm-001' (named 'realm1') started
2018-09-02T22:15:25+0900 [Router 1498] Starting role "role-001" on realm "realm-001"
2018-09-02T22:15:25+0900 [Router 1498] role role-001 on realm realm-001 started
2018-09-02T22:15:25+0900 [Controller 1495] Router "worker-001": role 'role-001' (named 'anonymous') started on realm 'realm-001'
2018-09-02T22:15:25+0900 [Router 1498] Starting router transport "transport-001"
2018-09-02T22:15:25+0900 [Router 1498] Creating router transport for "transport-001"
2018-09-02T22:15:25+0900 [Router 1498] Router transport created for "transport-001"
2018-09-02T22:15:25+0900 [Router 1498] UniSocketServerFactory starting on 8080
2018-09-02T22:15:25+0900 [Controller 1495] Router "worker-001": transport 'transport-001' started
2018-09-02T22:15:25+0900 [Router 1498] Starting "nodeinfo" Web service on path "info" of transport "transport-001"
2018-09-02T22:15:25+0900 [Controller 1495] Router "worker-001": web service 'nodeinfo' started on path 'info' on transport 'transport-001'
2018-09-02T22:15:25+0900 [Controller 1495] Local node configuration applied successfully!
設定ファイルが正しく読み込まれ、起動に成功すると最後にLocal node configuration applied successfully!
と出力されます。
crossbarにはWebサーバーが組み込まれています。ブラウザでhttp://localhost:8080/info/
にアクセスするとバージョン情報のページが表示されます。
確認が終わったら一旦Ctrl-C
でcrossbarを終了してください。以上でWAMPルーターcrossbarのインストールは完了です。
クライアント用ライブラリAutobahn(アウトバーン)
WAMPアプリケーションは複数のWAMPクライアント間の相互通信によって成り立ちます。WAMPルーターはこの通信を仲介するものであり、アプリケーションの主役はクライアントの方になります。crossbar.ioはWAMPクライアント開発用のライブラリとしてAutobahnを提供しています。こちらもオープンソースです。Python、JavaScript、C、C++、Java用が用意されています。
ほかにサードパーティのWAMPライブラリが数多くあります。以下のサイトに一覧が掲載されているので、開発に上記以外の言語を使いたい場合は参考にしてください。
なおcrossbar自体がAutobahn Pythonを使って書かれているため、crossbarをインストールするだけでAutobahn Pythonも自動的に使えるようになります。crossbarと同じPython venv環境を使う場合、別途インストールの必要はありません。
サンプルプログラムの実行
WAMPルータの設定とWAMPクライアント・プログラムのサンプルは以下のgitリポジトリに置かれているので、これをダウンロードします。
各言語毎に様々なサンプルが用意されていますが、最も基本的なサンプルcrossbar-examples/hello/python/
を実行してみます。これはPythonで実装したクライアントとWebブラウザ上で動くJavaScriptクライアント間で、PubSubおよびRPCの簡単なやり取りを行う例です。
Webブラウザ側で動かすAutobahnJSもダウンロードしておきましょう。
使用するファイルはautobahn-js-browser/autobahn.min.js
です。このファイルをcrossbar-examples/hello/python/web
にサブディレクトリshared/autobahnを作成し、そこにコピーしてください。サンプルのファイル構成は次のようになります。
$ mkdir -p crossbar-examples/hello/python/web/shared/aut
obahn
$ cp autobahn-js-browser/autobahn.min.js crossbar-exampl
es/hello/python/web/shared/autobahn
$ cd crossbar-examples/hello/python
$ tree -a
.
├── .crossbar
│ └── config.json # crossbarの設定ファイル
├── README.md
├── hello.py # PythonのWAMPクライアント
└── web
├── index.html # WAMPクライアントのJavaScriptを含むhtml
└── shared
└── autobahn
└── autobahn.min.js # AutobahnJSライブラリ
4 directories, 5 files
準備ができたらcrossbarを起動します。Pythonクライアント・プログラムhello.pyは設定ファイルconfig.jsonでコンポーネントとして記述されているため、crossbarに組み込まれた形で自動起動します。
$ pwd
/Users/yasusii/github/crossbar-examples/hello/python
$ crossbar start
このhelloサンプルは次の4つの内容をそれぞれ1秒置きに実行します。
- PubSubトピックcom.example.onhelloにPythonクライアントが数値をインクリメントしながら送信、JavaScriptクライアント側で受信
- 同じトピックにJavaScriptクライアントがメッセージ'Hello'を送信、Pythonクライアント側で受信
- 2つの引数の加算結果を返すプロシージャadd2()をPythonクライアントが登録、JavaScriptクライアントから実行
- 2つの引数の乗算結果を返すプロシージャmul2()をJavaScriptクライアントが登録、Pythonクライアントから実行
crossbarの起動直後、コンソールには次のようにプロシージャadd2()の登録とPubSubトピックにカウンタの数値をpublishしている様子が繰り返し出力されます。
2018-09-03T22:08:38+0900 [Container 2103] procedure add2() registered
2018-09-03T22:08:38+0900 [Container 2103] published to 'oncounter' with counter 0
2018-09-03T22:08:39+0900 [Container 2103] published to 'oncounter' with counter 1
2018-09-03T22:08:40+0900 [Container 2103] published to 'oncounter' with count
続いてWebブラウザでhttp://localhost:8080/
にアクセス、JavaScriptクライアントを接続します。これでPythonクライアントとJavaScriptクライアント間の通信が開始されます。ブラウザのJavaScriptコンソールを確認してみましょう。次の4種類の内容が出力されているはずです。
-
on_counter() event received with counter n
: Pythonクライアントから受信したPubSubメッセージ -
published to topic 'com.example.onhello'
: PubSubメッセージの送信 -
add2() result: n
: Pythonクライアントから返ってきたプロシージャの実行結果 -
mul2() called with n1 and n2
: Pythonクライアントへのプロシージャ呼び出し
ブラウザ側を確認したらもう一度crossbar側のコンソールに戻って見てみましょう。ログに次の内容が加わっているはずです。
-
event for 'onhello' received: Hello from JavaScript (browser)
: JavaScriptクライアントから受信したPubSubメッセージ -
add2() called with n1 and n2
: JavaScriptクライアントへのプロシージャ呼び出し -
mul2() called with result: n
: JavaScriptクライアントから返ってきたプロシージャの実行結果
これらがどのようにプログラムとして書かれているのかはそれぞれのプログラムと設定ファイルを参照してください。
ここまで来れば、ほかのサンプルも実行し内容を確認できるはずです。