LoginSignup
7
6

More than 5 years have passed since last update.

PubNubをApache Camelからサクッと使ってWebsocket代替にする

Last updated at Posted at 2016-03-12

皆さんこんにちは。しうへいと申します。
今回はIoT向けBaaSであるPubNubに、Apache Camelから接続する方法について書きます。

PubNubを知った経緯

昨日3/11になりますが、集まれMilkcocoaオジサン。 Milkcocoa Meetup vol 8 という勉強会に参加してきました。

IoT向けBaaSとしてMilkcocoa の名前を最近よく聞いていたのと、自分自身その分野のサービスに興味があったので参加しましたが、スピーカーの皆さんが話される内容としては、そのままズバリIoTというよりは、MilkcocoaのリアルタイムWebサーバーとしての機能を活用したものが多く(もちろんセンサー系のデモもありました)、期待してたものと少し違ったかなぁ…と思っていました。

そんな折、最後のスピーカーとして、Milkcocoaエバンジェリストであるのびすけ@n0bisukeさんが、おもむろに

「PubNubって知ってる?」
「PubNubってイケてるらしいよ?」
「Milkcocoaは正直負けてるかもしんない」
「でも同じBaaSとして一緒に盛り上がっていけたらいいと思うんだよね」

(※記憶力ないので、ニュアンスで書いてます)

(追記)
のびすけさんから実際のスライドのURLをいただきましたので、こちらに関してはスライドをご覧ください。
https://speakerdeck.com/n0bisuke/pubnubtomilkcocoa-milkcocoameetup-vol9-number-mlkcca-5fen
(追記ここまで)

みたいな話をされて、ロックなエバンジェリストだなぁと思いつつ、そこでPubNubを知ることになりました。

リアルタイムWebサーバーをBaaSに移譲するというトレンド

「Backend as a Service」 という言葉の響きからは、自分はもっと大仰なものをイメージしていたのですが、もっとカジュアルに、リアルタイムWebサーバーとして使えばいいんじゃないの、というメッセージをスピーカーの皆さんから受信しました。最初は「それならApache CamelのWebsocketコンポーネントがあるからいいかなぁ」と思っていましたが、Websocketを実際扱う際の泥臭さは知るところでしたので、その部分だけ定評のある外部サービスに移譲するのも良いのかと思うようになりました。

PubNubには、Apache Camel向けのコンポーネントがすでにあった

Apache Camelについて簡単に説明すると、Javaプラットフォームで動作する、ライブラリ / サービス / フォーマット / プロトコル統合フレームワークです。ライブラリ / サービス / フォーマット / プロトコル同士の、n対nの接続および変換コードを個々に書くのは大変だから、n-x-nになるようなxを作ろう、みたいな発想から生まれたフレームワークです。

ちなみにApache Camelでは、n-xの部分をコンポーネントと呼んでいます。
2016年3月現在、コンポーネントはプロジェクトの外部で作られたものも合わせて200以上に達しています。

Apache Camel: Components http://camel.apache.org/components.html

驚くことに、今日知ったばかりのPubNubは、外部で作られたコンポーネントとして、既に上記に掲載されていました。
Camelライダーとしては、これは試してみるっきゃありません。

PubNubを使う準備をする

PubNub https://www.pubnub.com/
無題.png

登録に必要なのはメールアドレスくらいでした。
特につまづきポイントなく登録が完了したので割愛します。

PubNubアプリケーションを作成して、キーを入手

ログインして [CREATE NEW APP]ボタンからアプリケーションを作成して、適当な名前をつけます。自分は「myiot」としました。
無題2.png

アプリケーションの詳細に入っていくと、各種キー情報が表示されます。これでPubNub側は準備完了です。

無題3.png

Apache Camelを使う準備をする

IDE上でMavenプロジェクトを新規作成して、依存関係を記述します。
(自分は標準でビルドツールMavenが入っているNetBeans IDEを使ってます)
セントラル・リポジトリでcamel-pubnubと検索して、追加すれば良いです。
Apache Camel側のissueで、slf4j-simpleも追加します。これで標準出力にログが出力されます。

以下は自動生成されたpom.xmlです。

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mycode</groupId>
    <artifactId>myiot</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <dependencies>
        <dependency>
            <groupId>io.rhiot</groupId>
            <artifactId>camel-pubnub</artifactId>
            <version>0.1.4</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.6.6</version>
        </dependency>
    </dependencies>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
</project>

PubNubコンポーネントの使い方を確認する

以下にcamel-pubnubコンポーネントの使い方が書いてあります。
https://rhiot.gitbooks.io/rhiotdocumentation/content/cloudplatform/camel_components/camel_pubnub_component.html
Apache CamelではアクセスするリソースをURIとして記述する必要があります。この書き方が分かればよいので、General URI formatの辺りに目を通します。
無題4.png

基本は pubnub://pubsub:channel?options で、optionsにkeyが3種類設定されていれば使えそうです。

実行コードを書く

以下のコードサンプルでは、
送信側では一秒ごとにメッセージ"foo"をPubNubにポストします。
受信側ではPubNubから受信したメッセージを標準出力しています。

App.java
package com.mycode.myiot;

import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.main.Main;

public class App {
    public static void main(String[] args) throws Exception{
        Main main = new Main();
        main.addRouteBuilder(new RouteBuilder(){
            @Override
            public void configure() throws Exception { // ここまでApache Camelの基本共通コード

                String pubKey = "ゆ○式"; // 有効な値を設定されたし
                String subKey = "一般"; // 有効な値を設定されたし
                String secKey = "完売"; // 有効な値を設定されたし
                String pubnubEndpointUri = String.format("pubnub://pubsub:channel?publisherKey=%s&subscriberKey=%s&secretKey=%s", pubKey,subKey,secKey);

                // 送信側のルール定義
                from("timer:foo") // 1秒ごとに実行
                        .setBody(constant("foo")) // 送信内容を文字列"foo"に設定
                        .to(pubnubEndpointUri); // PubNubへ送信

                // 受信側のルール定義
                from(pubnubEndpointUri) // PubNubから受信
                        .to("log:foo"); // 受信内容をログに出力する

            } // ここからApache Camelの基本共通コード
        });
        main.run();
    }
}

実行結果

無題6.png

受信側に1秒ごとにfooが流れてきていることがわかります。ただこれだけだといまいちPubNubサーバーを通している感がないので、
ためしに、受信部分をコメントアウトした状態でApp.javaを実行します。その次に今度は送信部分をコメントアウトして、いくつかApp.javaを実行します。これにより簡易的に1対多のPub/Subを作り出します。

その場合でもやはりそれぞれにログが出力されますので、めでたくPubNubサーバーをApache Camelから使うことが出来た、ということのようです。

感想

勝手アプリを作成する際に、自前でWebsocketサーバーを立てることはもうなくなったかもなぁ、と思いました。
逆にこれまで「Websocketを使えば何とか実装できるかなぁ」でとどまっていたアイデアは、だいぶ実装しやすくなったと思います。ユーザーを識別するあたりの機能を検証する必要がありますが。

ごくごく個人的な、感想…

最近はまっているGoogleトレンドのスクリーンショットを載せておきます。(実際のページは画像をクリック)
無題7.png

Apache Camelの規模感を知る自分視点では、PubNubもなかなかイケてる規模感のようです。
(Milkcocoaは同名の対象が多いそうなのでやめておきました。)
PubNubもApache Camelも、国内では「知る人ぞ知る」製品だと思います。でもその「比較的知られていない」者の間にすでにコンポーネントが用意されているのですから、海外の器のデカさや先進性を実感させられます。

Milkcocoaの人は、現状だとApache Camelへの対応とか考えてないでしょうし、自分も別に求めていませんが、「PubNubに追いつけ追い越せ」論で行くと、
結局こういう細か~な対応状況で海外の製品とは差がつくのかなぁとも思ってます。
Milkcocoaに限らず国産製品全般の話ですが。どうしたらいいんでしょう。(ふわっとした終わり方)

7
6
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6