*

Node.jsのSocket.io入門

公開日: : 最終更新日:2015/11/12 投稿者:raru node, web技術

前置き

WebRTCを使用して通信を行なうときに、offerなどの情報を伝える為にサーバサイドのプログラムが必要になります。
そこでよく使用されるものがNode.jsです。

Node.jsで頻繁に使用されているモジュールの一つとしてSocket.ioが存在します。
このモジュールを使用することでリアルタイム双方向通信が可能になるわけですね。
通信について正直詳しくないのであまり喋らない方がいいのですが、今までは通信を行なう為にコネクションを2度張ったりしする必要があったのがwebsocket(プロトコル)ではコネクションを張りっぱなしにすることで通信の無駄を省くことが出来る&リアルタイム性が向上するということがあるようです。

僕は「ブラウザAからメッセージ送って、サーバが受け取ったその瞬間にブラウザBにデータを反映ってどうやるんだ? サーバからブラウザBを識別して送る? クライアントがサーバの状態変化を取得しにいく?」と悩んだことがあるので、その部分を簡単に行なってくれるSocket.ioはそれだけで便利なものに感じられました。

余談ですが、そのとき私は仕方なくクライアントで2秒ごとくらいにサーバに状態を取り行くように実装しました。ネット上にあるチャットサイトにウィンドウ複数開いてアクセスして、Aで送信したメッセージがBに瞬間で届くかどうか試したら数秒ラグがあったので、そこで妥協した形です。
ちなみにCometという技術? で実現可能だったらしいです。

Socket.ioのセットアップ

socket.ioを使用するときはクライアントとサーバでモジュールを読み込む必要があります。
nodeのモジュールをプロジェクトに組み込みにはプロジェクトのルート

npm install socket.io

を実行します。
-gオプションを付加するとグローバルインストールとなりますが、お勧めしません。(僕はしましたが)
基本的にモジュールはプロジェクト内で閉じていることが望ましいと思います。

これでプロジェクトにsocket.ioが準備出来ました。

クライアントでのモジュール呼び出し

これでプロジェクトにsocket.ioモジュールが設置されたので、クライアントのプログラムからこれを呼び出します。

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

htmlからこれを呼び出してください。
ここで少しよく理解していないのがsrcにあるパスです。
プロジェクトルートにnode_modulesフォルダがあるだけで/socket.ioフォルダがあるわけでもなく、node_modules/socket.io/socket.io.jsファイルがあるわけでもないのに、どこからファイルを呼び出しているのでしょうね。
調べろって話ですよね、すみません。

サーバでのモジュール呼び出し

サーバ処理でもモジュールを呼び出しましょう。

var io = require('socket.io').listen(80);

io.sockets.on('connection', function (socket) {
  socket.on('init', function (data) {
    console.log(data);
  });
});

require関数でsocket.ioを指定しています。
これによりsocket.ioモジュールを読み込み、メソッドチェーンでlisten関数にポート番号を渡しています。
これにより、80番ポートで受け付けるサーバが立ちます。
実際にはhttpモジュールやexpressモジュールを一緒に使うことが多いです。

私も以下のようにしています。

var express = require('express'),
    http = require('http'),
    app = express();

app.use(express.static(__dirname + '/public'));

var server = http.createServer(app).listen(3000);
console.log('server start:', 3000);

var io = require('socket.io'),
    io = io.listen(server);

ちなみに80番ポートは特権ポートと呼ばれている予約されたポート番号になるため管理者権限で実行しないければエラーになってしまいます。

データのやりとり

クライアントからサーバへデータを送信

まずクライアントからサーバへのデータ送信について見ていきたいと思います。

socket = io.connect("ws://"+ location.host);
socket.emit("init", "hello");

まず1行目でインスタンスを生成し、2行目でデータの送信を行なっています。
socket.ioではemit関数を使うことでデータの送信を行ないます。

また第一引数でしている”init”という文字列ですが、これがデータの受信側で着火するイベントになります。
この名前は実装者が自由に設定して構いません。
第二引数でしている”hello”という文字はデータに当たります。ここに渡したものが受信側にデータとして送信されます。
送信出来るデータには特に指定はなく沢山のデータを送りたいのであればjsonとして送信することも出来ます。

json形式でデータを送信するときには以下のようにすることで簡単に送ることが出来ます。

socket.json.emit("message", {data1: "hello", 
                             data2: "world",
                             data3: true});

クライアントからのデータをサーバで受信/送信

まずクライアントから送信されたデータの受信を行ないます。

sample = io.sockets.on('connection', function(socket) {
    socket.on('init', function(data){
        socket.broadcast.emit('init', data)
    });
    
    socket.on('message', function(data){
       socket.broadcast.emit('message', data.data2);
    });
});

1行目でクライアントからの接続イベントを取得して、接続して来ているコネクションをsocketに格納しています。

socket.on()関数がemitで送られて来たデータを受信します。
ここでon関数が2つ用意されていて、それぞれ’init’, ‘message’が指定してあるのが分かります。
これはクライアントから投げられたemitの第一引数にあたります。
こうすることでemit(‘init’, data);としたときにはon(‘init’, data);のイベントが着火され、messageのときはmessageが着火します。

emitとonは対になっているわけですね。
そして次にあるのが

socket.broadcast.emit()

これは自分以外の全てのsocketに対してデータを送信します。
ネットワークのブロードキャストと同じです。

これ以外にも実はsocket.ioにはデフォルトでルーム機能がついているので、ルーム内の全ての相手に送信という機能もあります。
またsocket.idで一意なidを取得することが出来るので、実装次第では特定の一人に対してデータを送ることも可能です。

サーバからのデータをクライアントで受信

最後にサーバから投げられたデータの取得です。

socket.on('init', function(data) {
    alert(data);
});

socket.on('message' function(data){
    alert(data);
}

サーバ側と同じですね。
繰り返しになりますがsocket.ioでは受信がon, 送信がemitなのです。
これはクライアントでもサーバでも変わりません。
そもそも同じモジュールをインポートしていますからね。

終わりに

駆け足になってしまいましたが、socket.ioについては基本的にこれだけです。
ルーム機能などについては次回まとめて。

これでWebRTCとSocket.ioを利用してビデオチャットが作成可能です。

関連記事

no image

IEとchromeでbeforeunloadをaタグのhrefに反応させずに利用……できなかった

今回beforeunloadが面倒な動きをしていたので調査&ある程度都合よくしてみました。 してみ

記事を読む

no image

Laravelでクラスをnewする

今回はLaravelでのクラスのnewの仕方です。 正確には、Laravelでの他ファイルで作成し

記事を読む

no image

WebRTC + Node によるルーム機能付きビデオチャット 2

前回の続き こちらは前回の記事の続きになります。 また前回の記事にコメントを頂いたのですが、

記事を読む

no image

Laravelでルーティングからview表示をしてみる

Laravelでのroutes.phpの設定と、bladeを利用してview表示を行います。 いろ

記事を読む

no image

Mac OS X (Yosemite) にLaravelをインストール

Max OS 10.10(yosemite)にPHPフレームワークのLaravelをインストールして

記事を読む

no image

Facebook APIを試してみました

Facebook APIが気になったのでちょっと試してみました。 まず私が勘違いしていたこと

記事を読む

no image

PHPでXMLをnamespaceを利用したxpathでnode取得

PHPでxmlを読み込んでxpathでnodeを取得して見たいと思います。 今回はyahooの形態

記事を読む

no image

node v0.11.8 npm エラー

webRTCとnodeを使っていろいろと作ろうとしているのですが、開発中に少し悩んだので備忘録

記事を読む

no image

MAMPでLaravelを動作させる

先日laravelをMAMPのhtdocsに配置しましたが、当然それでは動かなかったので設定しました

記事を読む

no image

socket.ioとwebRTCでビデオチャット

現在作成したいものがあるために、その予行演習として nodeのsocket.ioとwebRTC機能

記事を読む

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

PAGE TOP ↑