mBaaSお役立ちブログ

MQTTでmbaasにアクセスする

最近ホットなキーワードとして持ち上がっているのがIoT(Internet of Things:モノのインターネット)です。小さなデバイスとネットワークを組み合わせることで様々なセンサーから情報を取得し、それをスマートフォンやデスクトップコンピュータと組み合わせて利用できるようになります。もちろん別なデバイスにそのまま送信してM2M(Machine to Machine)も可能です。

IoTデバイスとmBaaS

先日はIoTとmBaaSの相性の良さについて紹介しました。ただ、いわゆるIoTではHTTPではなくMQTTと呼ばれるプロトコルに注目が集まっています。これはHTTPとは異なる軽量なプロトコルで、IoT向けに作られています。少量のデータを定期的に送受信させるのに向いたプロトコルです。

仕組みとしてはPub/Subとなっていて、発行側(Publisher)がサーバに送った情報を購読側(Subscriber)に転送するようになっています。PublisherはMQTTサーバに対して情報を発信し続けます。それはサーバを購読しているSubscriberに対して即座に伝えられますので、その後メッセージを処理すれば良いということになります。

今回はローカルでMQTTとニフティクラウド mobile backendを組み合わせてみたいと思います。

必要なもの

まずMQTTサーバを立てる必要があります。mosquittoというソフトウェアが知られています。Mac OSXであれば(かつHomebrewを使っていれば) brew install mosquitto でインストールできます。

Windowsの場合はバイナリが配布されていますのでダウンロードします。

起動は mosquitto を実行するだけです。

$ mosquitto
1418092937: mosquitto version 1.3.4 (build date 2014-12-09 10:34:51+0900) starting
1418092937: Using default config.
1418092937: Opening ipv4 listen socket on port 1883.
1418092937: Opening ipv6 listen socket on port 1883.

このように1883番ポートで待ち受けになります。

Subscriber(購読側)の準備

では次に購読側を準備します。以下のようなスクリプト(Ruby)になります。

require 'mqtt'
require 'uri'
require 'ncmb'

# Create a hash with the connection parameters from the URL
uri = URI.parse ENV['CLOUDMQTT_URL'] || 'mqtt://localhost:1883'
conn_opts = {
  remote_host: uri.host,
  remote_port: uri.port,
  username: uri.user,
  password: uri.password,
}

MQTT::Client.connect(conn_opts) do |c|
  NCMB.initialize application_key: ENV['APPLICATION_KEY'] || "",  client_key: ENV['CLIENT_KEY'] || ""
  loop do
    # The block will be called when you messages arrive to the topic
    c.get(ENV['TOPIC']) do |topic, message|
      puts "Hello"
      @push = NCMB::Push.new
      @push.immediateDeliveryFlag = true
      @push.target = ['ios']
      @push.message = message.force_encoding('utf-8')
      @push.deliveryExpirationTime = "3 day"
      @push.save
    end
  end
end

メッセージを受け取ったら、その内容をニフティクラウド mobile backendにプッシュ通知登録しています。例えばArduino、Raspberry PIでセンサーを監視し、閾値を超えた段階でMQTTサーバにPublishすると、それがそのままプッシュ通知につながるといった形です。これはもちろんデータストアに保存するようにしても良いでしょう。

環境変数含めて次のように起動します。app_keyおよびclient_keyはそれぞれ読み替えてください。

$ APPLICATION_KEY=app_key CLIENT_KEY=client_key TOPIC=helloncmb ruby app.rb

Publisher(発行側)の準備

このスクリプトを実行した後、コンソール(irb)でメッセージを送ってみます。

require 'mqtt'
require 'uri'
uri = URI.parse 'mqtt://localhost:1883'
conn_opts = {
  remote_host: uri.host,
  remote_port: uri.port,
  username: uri.user,
  password: uri.password,
}
c = MQTT::Client.connect(conn_opts)

これでサーバに接続されました。メッセージの送信はトピックとメッセージの組み合わせになります。

c.publish 'helloncmb', "こんにちは MQTT"
 => 33

そうすると少し待てば登録していたデバイスにプッシュ通知が届くはずです。

MQTT経由でのプッシュ通知例

今回のコードはGitHubにアップロードしてあります。Heroku buttonに対応させてありますが、CloudMQTTとHerokuのつなぎ込みがうまくいっていませんのでご注意ください(ローカルで試す限りは大丈夫です)。

MQTTは今後IoT対応を考える上で大事なプロトコルになります。とはいえ署名生成などをIoTデバイスで行うのは難問であるため、一旦外部のサーバを介してニフティクラウド mobile backendにデータ蓄積するのがおすすめです。





ニフティクラウドmobile backend mbaas ご紹介 概要資料