はじめに
PC <-> モバイルアプリ間のデータ通信にPublish/Subscribeメッセージモデルを利用しています。今はPubNubを使っていますが、スケールや価格を考慮してGoogle Cloud Pub/Subへの移行を検討しています。今回はGoogle Cloud Pub/Subをとりあえず使ってみた時のメモです。
やりたいこと
- PC Webのある画面でモバイルアプリからのデータを待ち受ける。(Subscribe)
- モバイルアプリからPC Webにデータ連携。(Publish)
※ 今回の内容は、1Publisherに対して、1Subscriberを想定しています。PC Webとモバイル間でTopic情報を連携する必要がありますがこの記事ではその部分は省略します。
Google Cloud Pub/Subの構成
Cloud Pub/Subの構成は以下のようになっていて、Publishする時は、事前に作成したTopicに対してメッセージを送信します。
とりあえず使ってみましょう
GithubにあるGoogle Cloud Node.js Clientを使います。
1. 事前準備
1, Google Developers Consoleを開く
2, プロジェクトを作成、または既存のプロジェクトを選択
3, メニューからAPI Managerを選択して、以下APIを有効にする
Google Cloud Datastore API
Google Cloud Storage
Google Cloud Storage JSON API
4, 認証情報メニューからサービスアカウントキーを作成後、JSONファイルを保存
5, ローカルPCに適当なディレクトリを作成して、Google Cloud Node.js Clientをインストール
$ npm install @google-cloud/pubsub --save
6, 5のディレクトリに認証用JSONファイルを保存
7, 以下のようなディレクトリ構造になります。(subscribe.js, publish.jsについては後述)
pub-sub-sample
├── subscribe.js
├── publish.js
├── sample-project-1234567890.json
├── node_modules
└── gcloud
2. subscribe.jsを実装
subscribe.jsでは以下を処理します。
- Topic作成
- Subscribe
- データ受信後ログに表示
- Topic削除
- データ受信リスナー削除
const Pubsub = require('@google-cloud/pubsub');
const pubsub = Pubsub({
projectId: 'sample-project',
keyFilename: '/tmp/sample-project-1234567890.json'
});
const topicName = 'info'
const subscriptionName = 'info-subscription'
// Create Topic
pubsub.createTopic(topicName, function(err, topic, apiResponse) {
if(err){
if (err.code === 6) {
// topic already exists.
topic = pubsub.topic(topicName)
}else{
// Error check e.g. Authentication Check
console.log('err ',err);
return;
}
}
// Create Subscription
topic.createSubscription(subscriptionName, (err, sub) => {
if (err) {
console.error("create subscription error topic:", subscriptionName)
return;
}
subscription = sub;
subscription.on('error', function(err) {
console.log('err');
});
// onMessage Callback
function onMessage(message) {
console.log(JSON.parse(message.data));
console.log(message.attributes);
// Remove Listener
subscription.removeListener('message', onMessage);
// Delete subscription
subscription.delete(function(err, apiResponse) {
if(err){
console.error("delete subscription error topic:", topicName)
return;
}
console.log(subscription.name + " is deleted");
});
// Delete topic
topic.delete(function(err, apiResponse) {
if(err){
console.error("delete topic error topic:", topicName)
return;
}
console.log(topic.name + " is deleted");
});
}
// Add Listener
subscription.on('message', onMessage);
});
});
3. publish.jsを実装
publish.jsでは以下を処理します。
- Publish
const Pubsub = require('@google-cloud/pubsub');
const pubsub = Pubsub({
projectId: 'sample-project',
keyFilename: '/tmp/sample-project-1234567890.json'
});
const registerMessage = {
data: {
userId: 3,
name: 'Stephen',
event: 'new user'
},
attributes: {
key: 'value',
hello: 'world'
}
};
// Publish
const topic = pubsub.topic('info');
const publisher = topic.publisher();
publisher.publish(Buffer.from(JSON.stringify(registerMessage)), function(err) {
if (err) {
console.log(err);
}
});
4. 実行
Terminalの画面を2画面用意して実行します。
4-1. Terminal1(PC Web)
$ node subscribe.js
4-2. Terminal2(モバイルアプリ)
$ node publish.js
4-3. Terminal1(PC Web)
Publishした結果が表示されます
$ node subscribe.js
{ userId: 3, name: 'Stephen', event: 'new user' }
{ hello: 'world', key: 'value' }
info is deleted
まとめ
なんとなく動くことは確認しました。次回はPubNubで懸念だった以下の件を確認する予定です。
- モバイルアプリからのPublish (Swift)
- 3G回線などのコネクション状態が悪い場合のエラーハンドリング。
参考
Google Cloud Client Library for Node.js
Google Cloud Pub/Sub Node.js Sample: TypeError: Cannot read property 'on' of null