Help us understand the problem. What is going on with this article?

Node.js+MQTT.js+Mosca を使ってみた

More than 1 year has passed since last update.

はじめに

最近になって Raspberry Pi を使い始めました。
Raspberry Pi とサーバで通信するのに MQTT プロトコルを使うことにしました。
また、Raspberry Pi 、サーバともに Node.js で書きたいと思いました。

MQTT とは

MQTT とは、IoT や M2M のためのメッセージ転送プロトコルです。
多数のデバイスの間で短いメッセージを頻繁に送受信することを想定しています。
プロトコルヘッダが小さく、通信量、CPU 負荷、電力消費などを抑えることができます。

メッセージの送信側を、Publisher (発行者) と呼びます。
メッセージの受信側は、Subscriber (購読者) です。Subscriber は Publisher に対してメッセージの購読を予め希望します。
このとき Publisher と Subscriber は直接通信でなく、それぞれ Broker (仲介者) に接続します。Publisher と Subscriber はクライアント、Broker はサーバに位置づけられます。
Publisher と Subscriber は1対1だけでなく、容易に1対多、多対多に対応できます。
Publisher が発行するメッセージは、トピックをつけて送信します。Subcriber は、トピックを指定して購読を希望します。

MQTT.js を使う

MQTT.js は、MQTT クライアントのためのライブラリです。Node.js およびブラウザの JavaScript で使用できます。

公式 https://www.npmjs.com/package/mqtt

まず Node.js で使用してみます。

  • Node.js 8.1.4
  • mqtt.js 2.9.2

ワークスペースを作る

インストールする

$ npm install mqtt

Publisher の実装

publisher.js
var mqtt = require('mqtt');
var client = mqtt.connect('mqtt://mosquitto.org');

client.on('connect', function(){
    console.log('publisher.connected.');
});

setInterval(function(){
    var message = Date.now().toString()/
    client.publish('topic0', message);
    console.log('publisher.publish:', message);
}, 1000);

まず、mqtt.connect() で、インスタンスを生成すると同時にサーバ (Broker) に接続します。
サーバ (Broker) は、既存のサービス (mqtt://mosquitto.org) を利用させて貰います。
続いて、client.publish() で、サーバ (Broker) にメッセージ送信します。このときトピックを指定します。
ここでは setInterval() を使ってループしています。Ctrl+C で終了させて下さい。

Subscriber の実装

subscriber.js
var mqtt = require('mqtt');
var client = mqtt.connect('mqtt://mosquitto.org');

client.on('connect', function(){
    console.log('subscriber.connected.');
});

client.subscribe('topic0', function(err, granted){
    console.log('subscriber.subscribed.');
});

client.on('message', function(topic, message){
    console.log('subscriber.on.message', 'topic:', topic, 'message:', message.toString());
});

まず、mqtt.connect() で、インスタンスを生成すると同時にサーバ (Broker) に接続します。
サーバ (Broker) は、既存のサービス (mqtt://mosquitto.org) を利用させて貰います。
続いて、client.subscribe() で、サーバ (Broker) に購読を希望します。このときトピックを指定します。前述の Publisher の実装と合わせて下さい。
サーバ (Broker) からメッセージが届くと client.on('messege', で受信できます。

実行する

$ node publisher.js
$ node subscriber.js

Mosca を使う

Mosca は、MQTT broker のためのライブラリです。Node.js で使用できます。

公式 http://www.mosca.io/

  • Node.js 8.1.4
  • Mosca 2.5.2

ワークスペースを作る

インストールする

$ npm install mosca

Broker の実装

broker.js
var mosca = require('mosca');
var server = new mosca.Server({
    port: 1883,
});

server.on('ready', function(){
    console.log('Server is ready.');
});

まず、new mosca.Server() でインスタンス生成します。
port は任意です。
これで、Publisher からメッセージを受信し、Subscriber にメッセージを転送できるようになっています。

broker.js
server.on('clientConnected', function(client){
    console.log('broker.on.connected.', 'client:', client.id);
});

server.on('clientDisconnected', function(client){
    console.log('broker.on.disconnected.', 'client:', client.id);
});

server.on('subscribed', function(topic, client){
    console.log('broker.on.subscribed.', 'client:', client.id, 'topic:', topic);
});

server.on('unsubscribed', function(topic, client){
    console.log('broker.on.unsubscribed.', 'client:', client.id); 
});

server.on('published', function(packet, client){
    if (/\/new\//.test(packet.topic)){
        return;
    }
    if (/\/disconnect\//.test(packet.topic)){
        return;
    }
    console.log('broker.on.published.', 'client:', client.id);
});

Publisher および Subscriber が接続すると server.on('clientConnected', で確認できます。なくても構いません。
Subscriber が購読希望すると server.on('subscribed', で確認できます。なくても構いません。
Publiser がメッセージ送信すると server.on('published', で確認できます。なくても構いません。Publisher や Subscriber が接続したときも発火するようです。なので packet.topic を確認します。

Publisher の実装

前述のコードを若干変更します。

publisher.js
var client = mqtt.connect({
    host: 'localhost',
    port: 1883,
    clientId: 'mqtt.publisher',
});

host および port は、前述の Broker の実装に合わせて下さい。
clientId は、指定しなければ自動でセットされます。ここでは確認のため指定しています。

Subscriber の実装

前述のコードを若干変更します。

subscriber.js
var client = mqtt.connect({
    host: 'localhost',
    port: 1883,
    clientId: 'mqtt.subscriber',
});

host および port は、前述の Broker の実装に合わせて下さい。
clientId は、指定しなければ自動でセットされます。ここでは確認のため指定しています。

実行する

$ node publisher.js
$ node subscriber.js
$ node broker.js

MQTT クライアントをブラウザで動かす

MQTT.js を使う

MQTT.js は、MQTT クライアントのためのライブラリで、Node.js およびブラウザの JavaScript で使用できます。

ブラウザで動くプログラムを作ってみます。

インストールする

今回は CDN を利用します。
https://unpkg.com/mqtt/dist/mqtt.min.js

Publisher の実装

publisher.html
<html>
<head>
    <script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
    <script src="https://unpkg.com/vue/dist/vue.min.js"></script>
</head>
<body>
    <script>
        var client = mqtt.connect({
            host: 'localhost',
            port: 3000,
            clientId: 'http.publisher'
        });
    </script>

    <div id='buttonPublish' v-on:click='doPublish'>[発行する]</div>

    <script>
        new Vue({
            el: '#buttonPublish',
            methods: {
                doPublish: function(){
                    client.publish('topic0', Date.now().toString());
                }
            }
        });
    </script>
</body>
</html>

mqtt.connect() で、インスタンスを生成すると同時にサーバ (Broker) に接続します。
host および port は、後述する Broker の実装に合わせて下さい。
clientId は、指定しなければ自動でセットされます。ここでは確認のため指定しています。
client.publish() で、サーバ (Broker) にメッセージ送信します。このときトピックを指定します。

ボタン押下時の処理は Vue.js を使っています。別のフレームワークでも構いません。

Subscriber の実装

subscriber.html
<html>
<head>
    <script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
    <script src="https://unpkg.com/vue/dist/vue.min.js"></script>
</head>
<body>
    <script>
        var client = mqtt.connect({
            host: 'localhost',
            port: 3000,
            clientId: 'http.subscriber'
        });

        client.subscribe('topic0');

        var data = {};
        data.messages = [];

        client.on('message', function(topic, payload){
            var message = String.fromCharCode.apply(null, payload);
            console.log(message);
            data.messages.push(message);
        });
    </script>

    <ul id='listMessage'>
        <li v-for='message in messages'>
            {{ message }}
        </li>
    </ul>

    <script>
        new Vue({
            el: '#listMessage',
            data: data
        });
    </script>
</body>
</html>

mqtt.connect() で、インスタンスを生成すると同時にサーバ (Broker) に接続します。
host および port は、後述する Broker の実装に合わせて下さい。
clientId は、指定しなければ自動でセットされます。ここでは確認のため指定しています。
client.subscribe() で、サーバ (Broker) に購読を希望します。このときトピックを指定します。前述の Publisher の実装と合わせて下さい。
サーバ (Broker) からメッセージが届くと client.on('messege', で受信できます。

受信結果を表示する処理は Vue.js を使っています。別のフレームワークでも構いません。

実行する

publisher.html および subscriber.html をブラウザで開きます。

サーバをブラウザの MQTT クライアントに対応させる

Mosca を使う

Mosca は、MQTT broker のためのライブラリで、Node.js で使用できます。

Broker の実装

前述のコードを利用します。以下のコードを追加します。

broker.js
var http = require('http');
var httpServer = http.createServer();
server.attachHttpServer(httpServer);
httpServer.listen(3000);

server は、従来の MQTT サーバのインスタンスです。attachHttpServer() で HTTP サーバのインスタンス httpServer と結びつけます。
httpServer.listen() で指定するポート番号は、前述のクライアントの実装に合わせて下さい。

実行する

$ node publisher.js
$ node subscriber.js
$ node broker.js

ブラウザの Publisher でメッセージ送信すると、ブラウザの Subscriber でメッセージ受信します。同時に Node.js の Subscriber でも従来通りメッセージ受信します。
Node.js の Publisher で送信されたメッセージも、ブラウザの Subscriber および Node.js の Subscriber で受信され表示されます。

tinymouse
SI 企業の SE であり、日曜プログラマであり、二児の父。
http://d.hatena.ne.jp/tinymouse/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした