chromebook 「だけ」で webrtcを動かそう

27
Chromebook 「だけ」で WebRTCを動かそう 2015.03.11 インフォコム株式会社 がねこまさし @massie_g

Upload: mganeko

Post on 14-Jul-2015

789 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Chromebook 「だけ」で WebRTCを動かそう

Chromebook 「だけ」でWebRTCを動かそう

2015.03.11

インフォコム株式会社

がねこまさし

@massie_g

Page 2: Chromebook 「だけ」で WebRTCを動かそう

ChromebookでWebRTC

• Chrome動く

• カメラ、マイクついている

• getUserMeida()できる

• PeerConnectionも使える

• USBカメラも認識する

WebRTC端末として使える

※WebRTC Conference Japan のLTでも言及– 実際に遠隔作業支援にWebRTCを使ってみた– http://www.slideshare.net/hondahiroyuki/web-rtc-con

Page 3: Chromebook 「だけ」で WebRTCを動かそう

Chromebook 「だけ」でWebRTC

• どんなとき?

–ネットワークにつながらなくても、デモしたい!

Page 4: Chromebook 「だけ」で WebRTCを動かそう

問題1: Webサーバー

• 問題1

– getUserMedia()は、file:// では使えない

→ http:// にはWebサーバーが必要

Webサーバー

Page 5: Chromebook 「だけ」で WebRTCを動かそう

マッチョな対策

• Chromebookを開発者モードに変更– 時間かかります– 初期化されます– セキュリティ警告多発します

• crouton を導入– Crouton Integration Chrome Extensionを使うと、

Chrome OSのシェルと同居できるらしい– http://www.softantenna.com/wp/hard/linux-

in-chrome-os/

• Linuxをインストール

※私は怖くなって、途中で引き返しました

Page 6: Chromebook 「だけ」で WebRTCを動かそう

別の方法を探す

• Chrome App というのがある

• Chrome.sockets.tcpServer というのが使える

– https://developer.chrome.com/apps/sockets_tcpServer

• なら、Webサーバーも作れるはず!

Page 7: Chromebook 「だけ」で WebRTCを動かそう

Webサーバー作りました

• Simple Web Server (Chrome ウェブストアで)–非常に簡易的なWebサーバー

– http://goo.gl/4sxGy9静的なファイルを数個だけホストできるhttp://localhost:3000//page1.html~ /page4.html/script1.js, /script2.js/sytle1.css, /style2.css

※こちらを参考にさせていだだきました。どうもありがとうございます!Chrome Appsで簡易Webサーバ構築 http://blog.asial.co.jp/1267

Appインストールには

ネットワーク接続必要です。あしからず

Page 8: Chromebook 「だけ」で WebRTCを動かそう

DEMO

• SWS 起動

• http://localhost:3000/に Chromeでアクセス

• SWSの page1.html に、下記内容をコピー

– https://gist.github.com/mganeko/ee1f644b08fdca6970ca

• http://localhost:3000/page1.htmlに Chromeでアクセス

– Start video

Page 9: Chromebook 「だけ」で WebRTCを動かそう

ちなみに、もっと良さげなのもあります

• Web Server for Chrome

– http://goo.gl/LI63mj

Page 10: Chromebook 「だけ」で WebRTCを動かそう

問題2:シグナリング

• Peer-to-Peer通信の前に、情報交換が必要

– SDP, ICE candidate

• 手動(コピペ)で交換、という手もあるけど…

– http://html5experts.jp/mganeko/5181/

• 今回はWebSocketでやりたい

シグナリングサーバー

Webサーバー

Page 11: Chromebook 「だけ」で WebRTCを動かそう

WebScoketサーバー作りました

• Simple Message Server (Chrome ウェブストアで)

– 非常に簡易的なWebSocketサーバー

– http://goo.gl/ekvQDy簡易メッセージサーバー、WebSocketサーバー・5クライアントまで同時接続

・サーバーメッセージを送信すると、他のクライアントに配信・テキストデータのみ対応

Appインストールには

ネットワーク接続必要です。あしからず

Page 12: Chromebook 「だけ」で WebRTCを動かそう

参考にさせていただきましたどうもありがとうございます!

• Google のサンプル– Chrome Commando TCP server

– https://github.com/GoogleChrome/chrome-app-samples/tree/master/samples/tcpserver

• WebSocket サーバの実装とプロトコル解説 (by Jxckさん)

– http://jxck.hatenablog.com/entry/20120725/1343174392

– https://gist.github.com/Jxck/3171239

• RFC 6455 - The WebSocket Protocol (日本語訳)– http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html

Page 13: Chromebook 「だけ」で WebRTCを動かそう

Simple Message Serverの動き

• 3001/tcpで待ち受け• Upgradeに対応• メッセージを送ると、他のクライアントに転送

• 制約– 対応するメッセージはテキストのみ– メッセージ長は、16bitまで。64bitには未対応– フラグメントの分割には未対応

Page 14: Chromebook 「だけ」で WebRTCを動かそう

クライアント側のコード抜粋// WebSocketサーバーに接続var url = 'ws://localhost:3001/';var ws = new WebSocket(url);

// SDP送信var msg = JSON.stringify(sessionDescription);ws.send(msg);

// ICE Candidate送信var candidate = {type: "candidate",

sdpMLineIndex: evt.candidate.sdpMLineIndex,sdpMid: evt.candidate.sdpMid,candidate: evt.candidate.candidate

};var msg = JSON.stringify(candidate);ws.send(msg);

Page 15: Chromebook 「だけ」で WebRTCを動かそう

クライアント側のコード抜粋2ws.onmessage = onMessage;

// メッセージハンドラfunction onMessage(raw_evt) {

var msg = raw_evt.data;var evt = JSON.parse(msg);

if (evt.type === 'offer') {// SDP offerを受け取った場合

} else if (evt.type === 'answer' && peerStarted) {// SDP answerを受け取った場合

} else if (evt.type === 'candidate' && peerStarted) {// ICE candidate を受け取った場合

}}

Page 16: Chromebook 「だけ」で WebRTCを動かそう

DEMO

• SWS 起動, SMS起動

• SWSのpage2.htmlに、次の内容をコピー

– https://gist.github.com/mganeko/4d0f84c383722d1fb963

• http://localhost:3000/page2.html

– Chromeの2つのタブで開く

• 通信してみる

– Start video, Start video, Connect

Page 17: Chromebook 「だけ」で WebRTCを動かそう

問題3:NAT越え

• NAT越えには、STUN/TURNサーバーが必要

• Chrome.sockets.udpがある

• なら、これも作れるはず!

Page 18: Chromebook 「だけ」で WebRTCを動かそう

問題3:NAT越え

• NAT越えには、STUN/TURNサーバーが必要

• Chrome.sockets.udpがある

• なら、これも作れるはず!

→作りません!

今回はChromebook「だけ」なので、NAT越えは発生しない

※誰か挑戦してみませんか?

Page 19: Chromebook 「だけ」で WebRTCを動かそう

まとめ

• Chromebook「だけ」でWebRTC通信してみた– Chrome Appを作成– 簡易Webサーバー、簡易WebSocketサーバー

• もちろん、他のプラットフォームでも利用可能– Windows, Mac OS X

• 一般的なサーバーアプリ、サーバ言語不要– No IIS, No Apache, No Nginx, No python, No node.js

• WebRTC体験、ハンズオンにも最適

→ 社内勉強会などで、ぜひ使ってください!

Page 20: Chromebook 「だけ」で WebRTCを動かそう

おまけ

ちょっとサーバー側の

ソースを見てみましょう

Page 21: Chromebook 「だけ」で WebRTCを動かそう

Web サーバー

Page 22: Chromebook 「だけ」で WebRTCを動かそう

ソケット作成、待ち受け// serverchrome.sockets.tcpServer.create({}, function(createInfo) {

// サーバ用のソケットserverSocketId = createInfo.socketId;// 3000番ポートをlisten

chrome.sockets.tcpServer.listen(serverSocketId, '0.0.0.0', 3000, function(resultCode){if (resultCode < 0) {

console.log("Error listening:" + chrome.runtime.lastError.message); }

});});

// socketchrome.sockets.tcpServer.onAccept.addListener(function(info) {

if (info.socketId === serverSocketId) {chrome.sockets.tcp.setPaused(info.clientSocketId, false);

}});

Page 23: Chromebook 「だけ」で WebRTCを動かそう

GET Requestの処理chrome.sockets.tcp.onReceive.addListener(function(info) {

var requestText = ab2str(info.data);var getpath = splitGetPath(requestText); // GET のパスを取得var type = getMIMEType(getpath); // パスの拡張子から、MIMEタイプを推定// --- make response ---var socketId = info.socketId; var message = getContentByPath(getpath); // 内容はchrome.storage.localに保存var utf8message = unescape(encodeURIComponent(message)); // utf8に変換var responseText = [

' HTTP/1.1 200 OK','Content-Type: ' + type,'Content-Length: ' + utf8message.length,'',utf8message

].join("\n"); // --- send response ---chrome.sockets.tcp.send(socketId, str2ab(responseText), function(info) {

if (info.resultCode < 0) { console.log("Error:" + chrome.runtime.lastError.message); }chrome.sockets.tcp.disconnect(socketId); // 成功しても、すぐに切断するchrome.sockets.tcp.close(socketId);

});});

Page 24: Chromebook 「だけ」で WebRTCを動かそう

WebSokcetサーバー

Page 25: Chromebook 「だけ」で WebRTCを動かそう

コードの一部:データ長16bitまで対応

/*** Payload Length* xaaa aaaa second byte* 0111 1111 mask with 0x7f* ---------* 0000 0100 4(4)* 0111 1110 126(next UInt16)* 0111 1111 127(next UInt64)*/

var payloadLength = (secondByte & 0x7f); // 0x00~0x7c → その7bit値が長さif (payloadLength === 0x7e) { // 0x7e → 続く16bit値が長さ

console.log('next 16bit is length');payloadLength = dataView.getUint16(dataOffset); dataOffset += 2;

}if (payloadLength === 0x7f) { // 0x7f → 続く64bit値が長さ

console.error('next 64bit is length but not supported');}

Page 26: Chromebook 「だけ」で WebRTCを動かそう

コードの一部:mask処理の可変長対応

var maskingArray = new Uint8Array( [dataView.getUint8(dataOffset), dataView.getUint8(dataOffset+1), dataView.getUint8(dataOffset+2),dataView.getUint8(dataOffset+3)

]);dataOffset += 4;

for(payloadIndex = 0, maskOffset=0; payloadIndex < payloadLength; payloadIndex++, maskOffset = (maskOffset + 1) % 4) { // maskを4バイト毎に繰返す

var applicationByte = dataView.getUint8(dataOffset + payloadIndex);

/*** unmask the data* application data XOR mask

*/var unmaskedByte = applicationByte ^ maskingArray[maskOffset];applicationText += String.fromCharCode( unmaskedByte );

}

Page 27: Chromebook 「だけ」で WebRTCを動かそう

END

ありがとうございました!