Node.jsとSocket.IOによるPCとスマホブラウザのペアリングデモ

Node.jsとSocket.IOによるPCとスマホブラウザのペアリングデモ

※この記事が公開されたのは1年7ヶ月前ですが、 2015年11月16日に内容をメンテナンスしています。

地図上での現在地表示やSNSにおけるプッシュ通知等、リアルタイムなデータ通信はインタラクティブなWebコンテンツには不可欠の要素です。今回はリアルタイムなデータ通信を簡単にしてくれるSocket.IOを使ってPCとスマホがペアリングするコンテンツを作りました。Socket.IOの簡単な解説と共に紹介します。

※ ファイアーウォールの設定によっては閲覧できない可能性があります。デモ動画も御覧ください。

※ 全ソースコードをDLし解凍後のフォルダにてコマンドラインで「node server」を実行後、http://localhost:5000にアクセスするとローカル環境でもデモを確認できます。

デモについて

アクセスするとURLとペアリングコードが表示されます。以下、この画面をメイン画面と呼びます。指定のURLにスマホブラウザ等の別クライアント(ブラウザの別タブ、他の端末のブラウザ等。以下、コントローラと呼びます)でアクセスしてペアリングコードを入力するとその2つのクライアントが連携します。フリックするとメイン画面でパーティクルが発生します。また、1つのペアリングコードを使って複数のメイン画面をコントロールすることも可能です。

リアルタイムWebの実現とSocket.IO

Web上においてリアルタイムの通信を実現するには、WebSocketCometといった技術があり、ブラウザによってその実装状況やAPIも様々です。Socket.IOはこれらのさまざまな実装の差異を吸収し統一されたAPIで使えるようにしたNode.jsの技術です。Node.jsとSocket.IOで構築されたWebサーバーにクライアントがWebブラウザを使ってアクセスすると、サーバーとリアルタイムにデータを送受信できるようになります。開発者はブラウザ間の実装の差異を意識することなくリアルタイムな通信処理を実現できます。

socket_sample1644

Node.jsとhttpサーバー、Socket.IOの準備

さて、ここからはSocket.IOの簡単な使い方について説明していきます。まず、Socket.IOを使用するにはNode.jsが必要なので公式サイトよりインストーラーをダウンロードし手順にしたがってインストールしてください。インストール後、コマンドラインにてnode -vと実行し、Nodeのバージョンが表示されていればインストール成功です。

Node.jsインストール画面

つづいて、Node.jsが動作するhttpサーバーを準備します。もしお手元にNode.jsのhttpサーバーが存在しない場合は下記のファイルを使用してください。Node.jsのhttpモジュールfsモジュールを使ったシンプルなhttpサーバーです。Node.jsの処理はserver.jsに記述してあります。

上記をダウンロードして解凍しコマンドラインでそのフォルダに移動して「node (サーバーサイドのJavaScriptのスクリプト名)」を実行するとhttp://localhost:5000にてローカルサーバーが起動します。今回のデモはserver.jsがサーバーサイドのスクリプト名なので、「node server」と実行します。今回のSocket.IOはもちろん、Node.jsを試してみたい場合はこのserver.jsに処理を追記すると便利です。 ※ ファイアーウォールの設定によっては5000ポートでは起動できない場合があります。 ※ 今回はサーバーサイドのJavaScriptとクライアントのファイルを全てルート直下に配置します。

【コマンドライン】

// Windowsでの移動
cd C:¥Users¥MyName¥sample_server
// Macでの移動
cd /Users/MyName/sample_server
// httpサーバーの起動
node server

Socket.IOは以下のコマンドでインストールできます。今回使用したSocket.IOのバージョンは執筆時点(2014/12/22)の最新バージョンである1.2.1です。

【コマンドライン】

// Socket.IOのインストールコマンド
npm install socket.io

Socket.IOの使い方

サーバー側での処理

Node.jsで立てられたhttpサーバーが「server」オブジェクトに格納されているとします。このhttpサーバーでSoclet.IOを使うには以下のようにします。

【サーバー側のJavaScript】

// socket.ioの読み込み
var socketIO = require("socket.io");
// サーバーでSocket.IOを使える状態にする
var io = socketIO.listen(server);

このNode.jsが動いているサーバーにクライアントのアクセスがあった場合、io.socketsのconnectionイベントが発生します。この時発行されるsocketオブジェクトを使ってクライアントとのデータのやりとりをします。「dataName1」という名前で{ hoge : 1 }というデータをクライアントに送信し、「dataName2」という名前の{ fuga : “piyo” }というデータをクライアントから受信するコードの例を紹介します。

【サーバー側のJavaScript】

// サーバーへのアクセスを監視。アクセスがあったらコールバックが実行
io.sockets.on("connection", function (socket) {
    var dataToClient = {hoge : 1 };   // クライアントに送信するデータ例
    // 接続元のクライアントだけにデータ送信。
    socket.emit("dataName1", dataToClient);
    // 接続元のクライアント以外にデータ送信
    socket.broadcast.emit("dataName1", dataToClient);

    // クライアントからのデータの受信
    socket.on("dataName2", function(dataFromClient) {
        // 「piyo」という文字列がターミナルに出力される。
        console.log(dataFromClient.fuga);
    });
});

クライアント側でSocket.IOを使う

まず、クライアント側からSocket.IOを扱う為のJavaScriptであるsocket.io.jsを読み込みます。socket.io.jsはサーバー側でsocketIO.listen(server)(上記参照)を実行すると自動的に用意されるJavaScriptで、(サーバーのURL)/socket.io/socket.io.jsの場所に用意されます。

【HTMLコード】

<script src="/socket.io/socket.io.js"></script>
<script src="/js/main.js"></script>

Socket.IOを使ってサーバーと接続するにはio.connect()を使います。ここで生成されるsocketオブジェクトを使ってサーバー側とデータをやりとりします。「dataName2」という名前で{ fuga : “piyo” }というデータをサーバーに送信し、「dataName1」という名前の{ hoge : 1 }というデータをサーバーから受信するコードの例を紹介します。サーバー側のAPIと見比べるとわかるように、サーバー側とクライアント側のAPIは共通しており扱いやすいものとなっています。

【クライアント側のJavaScript main.js】

// サーバーに接続
var socket = io.connect(location.origin);
// サーバーへデータを送信
socket.emit("dataName2", { fuga : "piyo" });
// サーバーからのデータを受信
socket.on("dataName1", function(dataFromServer) {
    // 「1」という数値がブラウザのコンソールに出力される。
    console.log(dataFromServer.hoge);
});

上記コードのデモ

説明したコードを記述した簡単なSocket.IOのデモを準備しました。上記ファイルをダウンロードして解凍したファルダに移動して、コマンドラインでnode serverを実行してみてください。ブラウザのコンソールに「1」、コマンドラインに「fuga」が表示されていることが確認できます。

ペアリングを行う

今回のデモでは、メイン画面側はクライアントAがアクセスしてきた際にランダムなコードを発行します。コントローラでそのコードを入力するとクライアントAとクライアントBがサーバー側で同じグループに分けられます。その同じグループ間でのみデータを送受信することで、ペアリングを実現しています。Socket.IOには、アクセス中のクライアントをグループ化し通信処理を分けるroom機能があります。

room機能説明 socket.join(“ルームID”)を実行することでそのクライアントは指定されたグループ(ルームと呼ぶ)に所属している状態になります。クライアントからサーバーへデータを送信する際、送信先のグループを指定することで任意のグループにのみデータを送信することができます。

【サーバー側クライアント側共通のJavaScript記述】

var data = { hoge : 1 }; // 送信データ例
// roomIDのグループ(ルーム)に入れる
socket.join("roomID");
// roomIDにデータを送信する
socket.to("roomID").emit("someData", data);

PaaS「Heroku」を使ってリモートサーバー公開

Node.jsのコンテンツをリモートサーバーで確認するにはそのコンテンツを実行するための環境が必要です。自前で準備するのは大変なので、その実行環境を提供してくれるサービスPaaS(Platform as a Service)を使うと便利です。今回はSalesforceのHerokuを使いました。Herokuの使い方やPaaSの説明は下記をご参照ください。公式ドキュメントにてHerokuでの公開手順がわかりやすく説明されています。

最後に

いかがでしょうか? 今回のSocket.IOを使ったサーバーとクライアント間のリアルタイムなデータ通信を使うとフロントエンドだけでは実現できない表現が可能になります。サーバーサイドにNode.jsを使用することでフロントエンドエンジニアにとっては使い慣れたJavaScriptで1つのコンテンツ制作を完結させられます。是非お試しください。


     最新記事の一覧へ 
公開 / 更新
鹿野 壮

鹿野 壮

ICS所属のインタラクションデザイナー。九州大学芸術工学部音響設計学科でインタラクティブコンテンツを学ぶ。AIR・Swiftを使ったアプリ開発とHTML5・CSS3・JavaScriptを使ったリッチなWebページ制作が得意。豚骨ラーメンが大好きです。QiitaTwitterでも情報発信中!