![](https://tech.aainc.co.jp/wordpress/wp-content/themes/techblog/img/thumbnail_default.png)
開発本部の長野です。
最近は主に社内のインフラや社内向けのツールの開発をしています。
前回まではCSS3+JavaScriptについて書いてきましたが、
最近気になっているWebRTCのライブラリの一つ、﹁PeerJS﹂について調べてみたので、その導入から簡単なチャットプログラム作成までを紹介します。
そもそもWebRTCとは、wikipediaによると
WebRTC (Web Real-Time Communication)とはWorld Wide Web Consortium (W3C)が提唱するAPIの定義で、プラグイン無しでブラウザ間の音声通話︵英語版︶、ビデオチャット︵英語版︶、P2Pファイル共有︵英語版︶を可能にする。
とあります。つまりサーバーを介さずにブラウザ間で通信ができる技術のことです。
通信というあたりがWebSocketと似ていますが、詳しく知りたい方はHTML5で情報最適化/視覚化&WebRTCで変わる未来~QCon Tokyo 2013レポート (2/3) – @ITを参照してください。
①PeerJSのアカウント作成
アカウント作成方法は以下のサイトで﹁Developer – Free﹂をクリックし、必要情報を入れるだけです。 http://peerjs.com/peerserver# アカウントを作成すると、APIキーが一つもらえます。 このAPIキーを使うとPeerJS側で用意してくれている仲介サーバーが使えるようになります。②サンプルプログラムを試す
PeerJSのトップページに、二つのブラウザ間でデータ渡しをするサンプルプログラムが書いてあります。 まずはこれを試してみました。 初めに受ける側を開いてから次に別のタブで送る側を開くと、受ける側に﹁Hi!﹂というメッセージが表示されます。受ける側
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<!DOCTYPE html> <html> <title>sample1-1</title> <meta charset="utf-8"> <script src="http://cdn.peerjs.com/0/peer.min.js"></script> <script> var peer = new Peer('ReceiverID', {key: '63jlsxinm7bke29'}); peer.on('connection', function(conn) { conn.on('data', function(data){ document.getElementById("receive_message").innerHTML = data; }); }); </script> <body> <div id="receive_message"></div> </body> </html> |
受ける側の解説
1 2 3 4 5 6 |
var peer = new Peer('ReceiverID', {key: '63jlsxinm7bke29'}); peer.on('connection', function(conn) { conn.on('data', function(data){ document.getElementById("receive_message").innerHTML = data; }); }); |
1行目でpeerのオブジェクトを作成しています。
第1引数には自分のIDを入れます。
このIDを指定することで別のブラウザから接続できる仕組みになっています。
第2引数はPeerJSに登録した時にもらったAPIキーを入れます。
2行目は別のブラウザから接続されたときに呼ばれるイベントハンドラで、
3〜5行目にデータが送られてきた際の処理を書きます。
このサンプルでは送られたデータをreceive_messageというdivタグに吐くようにしています。
送る側
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<!DOCTYPE html> <html> <title>sample1-2</title> <meta charset="utf-8"> <script src="http://cdn.peerjs.com/0/peer.min.js"></script> <script> var peer = new Peer('SenderID', {key: '63jlsxinm7bke29'}); var conn = peer.connect('ReceiverID'); conn.on('open', function(){ conn.send('hi!'); }); </script> <body> </body> </html> |
送る側の解説
1 2 3 4 5 |
var peer = new Peer('SenderID', {key: '63jlsxinm7bke29'}); var conn = peer.connect('ReceiverID'); conn.on('open', function(){ conn.send('hi!'); }); |
1行目はID以外受ける側と同じです。
2行目で受ける側のIDを指定して接続を試みています。
このときに﹁DataConnection﹂と呼ばれる接続相手と通信を行うためのオブジェクトが帰ってきます。
3行目は接続が成功したときに呼ばれるイベントハンドラです。
4行目でhi!と言うメッセージを送っています。
③チャット用に変更する
上記のサンプルプログラムを双方向でメッセージが行えるように変更してみました。1つ目のブラウザ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<!DOCTYPE html> <html> <title>sample2-1</title> <meta charset="utf-8"> <script src="http://cdn.peerjs.com/0/peer.min.js"></script> <script> var selfId = "ReceiverID"; var againstId = "SenderID"; var conn; var peer = new Peer(selfId, {key: '63jlsxinm7bke29'}); function connect(c) { conn = c; conn.on('data', function(data){ document.getElementById("receive_message").innerHTML += againstId + ":" + data + "<br />"; }); conn.on('close', function(err){ alert(conn.peer + ' has left the chat.') }); }; function sendMessage(){ document.getElementById("receive_message").innerHTML += selfId + ":" + document.getElementById("message").value + "<br />"; conn.send(document.getElementById("message").value); } peer.on('connection', connect); </script> <body> <input type="text" id="message"><input type="button" onClick="sendMessage();" value="送る" /> <div id="receive_message"></div> </body> </html> |
2つ目のブラウザ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<!DOCTYPE html> <html> <title>sample2-2</title> <meta charset="utf-8"> <script src="http://cdn.peerjs.com/0/peer.min.js"></script> <script> var selfId = "SenderID"; var againstId = "ReceiverID"; var conn; var peer = new Peer(selfId, {key: '63jlsxinm7bke29'}); function connect(c) { conn = c; conn.on('data', function(data){ document.getElementById("receive_message").innerHTML += againstId + ":" + data + "<br />"; }); conn.on('close', function(err){ alert(conn.peer + ' has left the chat.') }); }; function sendMessage(){ document.getElementById("receive_message").innerHTML += selfId + ":" + document.getElementById("message").value + "<br />"; conn.send(document.getElementById("message").value); } function onBodyLoad(){ var c = peer.connect(againstId, {serialization: 'binary-utf8'}); c.on('open', function(){ connect(c); }); } </script> <body onload="onBodyLoad();"> <input type="text" id="message"><input type="button" onClick="sendMessage();" value="送る" /> <div id="receive_message"></div> </body> </html> |
解説
まず1つ目と2つ目の違いは「selfId」と「againstId」の中身が逆になっていることと、
二つ目がonload時に一つ目のブラウザに対して接続を行っていること以外はほとんど同じです。
時系列に解説します。
■一つ目のブラウザを開く
1 |
var peer = new Peer(selfId, {key: '63jlsxinm7bke29'}); |
①Peerを”ReceiverID”というIDでnewする。
1 |
peer.on('connection', connect); |
②別のブラウザからの接続を待つ
■二つ目のブラウザを開く
1 |
var peer = new Peer(selfId, {key: '63jlsxinm7bke29'}); |
③Peerを”SenderID”というIDを引数でnewする。
1 2 3 4 5 6 |
function onBodyLoad(){ var c = peer.connect(againstId, {serialization: 'binary-utf8'}); c.on('open', function(){ connect(c); }); } |
④onBodyLoadで”ReceiverID”に接続を試みる。
(このときに第二引数に’binary-utf8’と入れることで日本語も送れるようになります。)
接続が成功したらconnect関数を呼ぶ。
また、このときに一つ目のブラウザのconnect関数も呼ばれる。
1 2 3 4 5 6 7 |
function connect(c) { conn = c; conn.on('data', function(data){ document.getElementById("receive_message").innerHTML += againstId + ":" + data + "<br />"; }); conn.on('close', function(err){ alert(conn.peer + ' has left the chat.') }); }; |
⑤両方のブラウザのconnect関数が呼ばれ、引数には接続相手のDataConnectionが入っている。
送信のときに使えるようにグローバル変数にセットし、データ受信用のイベントハンドラを呼ぶ。
1 2 3 4 |
function sendMessage(){ document.getElementById("receive_message").innerHTML += selfId + ":" + document.getElementById("message").value + "<br />"; conn.send(document.getElementById("message").value); } |
⑥送信ボタンを押したときの処理。
以上で完成です。
完全なチャットのシステムにするには
・アクセスするブラウザに応じてIDを変える
・ユーザー名も入力できるようにする
等しなくてはいけませんね。
このWebRTCですが、動画や音声も送受信でき、モバイルでは最新のandroid版chromeで使えます。︵要コンフィグ変更︶
今後iOSでも使えるようになればP2Pのサービスが増えていろいろ遊べそうですね。
最後にアライドアーキテクツでは、一緒に働いてくれるエンジニアを募集中です。
興味がある方は、こちらの採用サイトからご応募ください。
サービス開発や社内インフラ等を担当しています。 このブログではJavaScript周りのネタを中心に書いていきたいです。