Weitere ähnliche Inhalte Ähnlich wie Chromebook 「だけ」で WebRTCを動かそう (20) Kürzlich hochgeladen (10) Chromebook 「だけ」で WebRTCを動かそう2. Chromebook で WebRTC
• Chrome動く
• カメラ、マイクついている
• getUserMeida()できる
• PeerConnectionも使える
• USBカメラも認識する
WebRTC端末として使える
※WebRTC Conference Japan のLTでも言及
– 実際に遠隔作業支援にWebRTCを使ってみた
– http://www.slideshare.net/hondahiroyuki/web-rtc-con
5. マッチョな対策
• Chromebookを開発者モードに変更
– 時間かかります
– 初期化されます
– セキュリティ警告多発します
• crouton を導入
– Crouton Integration Chrome Extensionを使うと、
Chrome OSのシェルと同居できるらしい
– http://www.softantenna.com/wp/hard/linux-
in-chrome-os/
• Linuxをインストール
※私は怖くなって、途中で引き返しました
6. 別の方法を探す
• Chrome App というのがある
• Chrome.sockets.tcpServer というのが使える
– https://developer.chrome.com/apps/sockets_tcpS
erver
• なら、Webサーバーも作れるはず!
7. 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インストールには
ネットワーク接続必要
です。あしからず
8. DEMO
• SWS 起動
• http://localhost:3000/ に Chromeでアクセス
• SWSの page1.html に、下記内容をコピー
– https://gist.github.com/mganeko/ee1f644b08fdca
6970ca
• http://localhost:3000/page1.html に Chrome
でアクセス
– Start video
11. WebScoketサーバー作りました
• Simple Message Server (Chrome ウェブストアで)
– 非常に簡易的なWebSocketサーバー
– http://goo.gl/ekvQDy
簡易メッセージサーバー、
WebSocketサーバー
・5クライアントまで同時接続
・サーバーメッセージを送信す
ると、他のクライアントに配信
・テキストデータのみ対応
Appインストールには
ネットワーク接続必要
です。あしからず
12. 参考にさせていただきました
どうもありがとうございます!
• 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
13. Simple Message Serverの動き
• 3001/tcpで待ち受け
• Upgradeに対応
• メッセージを送ると、他のクライアントに転送
• 制約
– 対応するメッセージはテキストのみ
– メッセージ長は、16bitまで。64bitには未対応
– フラグメントの分割には未対応
14. クライアント側のコード抜粋
// 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);
15. クライアント側のコード抜粋2
ws.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 を受け取った場合
}
}
16. DEMO
• SWS 起動, SMS起動
• SWSのpage2.htmlに、次の内容をコピー
– https://gist.github.com/mganeko/4d0f84c383722
d1fb963
• http://localhost:3000/page2.html
– Chromeの2つのタブで開く
• 通信してみる
– Start video, Start video, Connect
19. まとめ
• Chromebook「だけ」でWebRTC通信してみた
– Chrome Appを作成
– 簡易Webサーバー、簡易WebSocketサーバー
• もちろん、他のプラットフォームでも利用可能
– Windows, Mac OS X
• 一般的なサーバーアプリ、サーバ言語不要
– No IIS, No Apache, No Nginx, No python, No node.js
• WebRTC体験、ハンズオンにも最適
→ 社内勉強会などで、ぜひ使ってください!
22. ソケット作成、待ち受け
// server
chrome.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);
}
});
});
// socket
chrome.sockets.tcpServer.onAccept.addListener(function(info) {
if (info.socketId === serverSocketId) {
chrome.sockets.tcp.setPaused(info.clientSocketId, false);
}
});
23. 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);
});
});
25. コードの一部:データ長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');
}
26. コードの一部: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 );
}