Node.js with WebRTC DataChannel

32
Node.js with WebRTC DataChannel 東京Node学園祭2016 2016.11.12 がねこまさし @massie_g

Transcript of Node.js with WebRTC DataChannel

Page 1: Node.js with WebRTC DataChannel

Node.js with WebRTC DataChannel

東京Node学園祭2016 2016.11.12 がねこまさし

@massie_g

Page 2: Node.js with WebRTC DataChannel

自己紹介

• 所属 – インフォコム(株)の調査研究チーム Web担当

• Node学園の過去の発表 – 東京Node学園祭2014

• Nodeで操るKurentoメディアサーバー • http://www.slideshare.net/mganeko/nodekurento

– 東京Node学園祭2013 • WebRTCを始めよう • http://www.slideshare.net/mganeko/2013-web-rtcnode

• Web記事 – HTML5Experts.jp WebRTC入門2016

• https://html5experts.jp/series/webrtc2016/

Page 3: Node.js with WebRTC DataChannel

WebRTCとは

• Web Real-Time Communication の略

• Webブラウザ上のリアルタイム通信の規格 –ビデオ/オーディオ … MediaStream

–任意のデータ … DataChannel

• どこで使えるか? – PCブラウザ (Chrome, Firefox, もうすぐEdgeでも)

– Androidブラウザ (Chrome, Firefox)

–ネイティブアプリ (PC, Android, iOS, other)

– Node.js 用モジュール

Page 4: Node.js with WebRTC DataChannel

Node.jsでWebRTCを使う方法

• Node.js × ブラウザ – NW.js (node-webkit) … http://nwjs.io – Electron … http://electron.atom.io – どちらもデスクトップアプリケーション

• 中にChromiumを丸ごと持っているようなもの

• Node.js × libwebrtc – Chromiumの中から、WebRTCのライブラリのみ利用 – wrtc (node-webrtc) ... DataChannel のみ対応

• https://github.com/js-platform/node-webrtc

– webrtc-native … DataChannel、MediaStream両対応 • https://github.com/vmolsa/webrtc-native

Page 5: Node.js with WebRTC DataChannel

やりたいこと

P2Pのデータ通信

Webブラウザ Node.jsのアプリ

Page 6: Node.js with WebRTC DataChannel

Part 1 wrtc (node-webrtc)

Page 7: Node.js with WebRTC DataChannel

インストール方法

• Mac OS X 10.10.x / 10.11.x のケース

– npm install wrtc

• Ubutnu 16でも同様

• npm install wrtc

Page 8: Node.js with WebRTC DataChannel

使い方(1) 読み込み

var WebRTC = require('wrtc');

var RTCPeerConnection = WebRTC.RTCPeerConnection;

var RTCIceCandidate= WebRTC.RTCIceCandidate;

var RTCSessionDescription = WebRTC.RTCSessionDescription;

var RTCDataChannel = WebRTC.RTCDataChannel;

Page 9: Node.js with WebRTC DataChannel

使い方(2) シグナリング

• シグナリングとは – P2P通信をするために必要な情報を交換すること

• 今日はシグナリングの処理は省略

– 通常シグナリングサーバーを介して行う • WebSocketが使われることが多い(Socket.IOも含む) • 今回は、Socket.IOを利用

• 参考 – WebRTCハンズオン 概要編

• http://qiita.com/massie_g/items/916694413353a3293f73

– WebRTC入門2016 • https://html5experts.jp/mganeko/19814/ • https://html5experts.jp/mganeko/20013/ • https://html5experts.jp/mganeko/20112/

今回は手順は省略

Page 10: Node.js with WebRTC DataChannel

シグナリングサーバーとの関係

P2Pのデータ通信

シグナリングサーバー Node.js + Socket.IO 接続情報

(SDP) を交換

Node.jsのアプリ Socket.IOクライアント

Webブラウザ

Page 11: Node.js with WebRTC DataChannel

DataChannelを利用する(1) 始める側:ブラウザ

var peer = new RTCPeerConnection(config); // P2P通信を始める前(シグナリング前)に、DataChannelを用意する var dataChannel = peer.createDataChannel('channelName', option); dataChannel.onopen = function () { // 接続時の処理 }; dataChannel.onmessage = function (evt) { // データ受信時の処理 var data = evt.data; }; dataChannel.onerror = function (error) { // エラー時の処理 }; dataChannel.onclose = function () { // 切断時の処理 dataChannel = null; };

Page 12: Node.js with WebRTC DataChannel

DataChannelを利用する(2) 受ける側: Node.js

var peer = new RTCPeerConnection(config);

var dataChannel = null;

peer.ondatachannel = function(event) {

dataChannel = event.channel; // DataChannelを作るのではなく、渡されたものを使う

dataChannel.onopen = function () { // 接続時の処理

};

dataChannel.onmessage = function (evt) { // データ受信時の処理

var data = evt.data;

};

dataChannel.onerror = function (error) { // エラー時の処理

};

dataChannel.onclose = function () { // 切断時の処理

dataChannel = null;

};

};

Page 13: Node.js with WebRTC DataChannel

DataChannelを利用する(3) メッセージを送る: ブラウザ/Node.js

• dataChannel.send( data );

– dataの型

• DOMString, Blob, ArrayBuffer, ArrayBufferView

– dataChannelは双方向

Page 14: Node.js with WebRTC DataChannel

Demo 1: Echoサーバー

Page 15: Node.js with WebRTC DataChannel

Demo2:ターミナルソフト

Page 16: Node.js with WebRTC DataChannel

ターミナルの全体の構成 Node.jsのアプリ側 Webブラウザ側

pty.js xterm.js

DataChannel DataChannel

on.('data, … )

send() onmessage()

write() on.('data, … )

send()

onmessage()

write()

ユーザー bash

Page 17: Node.js with WebRTC DataChannel

ターミナルソフト Node.js側

• pty.js を利用 https://github.com/chjj/pty.js/

• インストール – npm install wrtc

– npm install socket.io-client

– npm install pty.js

• 利用 var WebRTC = require('wrtc');

var IOClient = require('socket.io-client');

var pty = require('pty.js');

参考

Page 18: Node.js with WebRTC DataChannel

pty.jsでターミナルを準備

var ptyTerm; function setupTerminal(cols, rows) { ptyTerm = pty.spawn(process.platform === 'win32' ? 'cmd.exe' : 'bash', [], { name: 'xterm-color', cols: cols || 80, rows: rows || 24, cwd: process.env.PWD, env: process.env }); ptyTerm.on('data', function(data) { dataChannel.send(data); // ターミナルから来たデータをDataChannelに送る }); }

参考

Page 19: Node.js with WebRTC DataChannel

DataChannel接続の処理

var dataChannel = null; peer.ondatachannel = function(event) { dataChannel = event.channel; // … 略 … dataChannel.onmessage = function (evt) { ptyTerm.write(evt.data); // ターミナルに送る }; // ターミナルを準備 setupTerminal(80, 25); };

参考

Page 20: Node.js with WebRTC DataChannel

ターミナルソフト ブラウザ側

• xterm.js を利用 https://github.com/sourcelair/xterm.js

• 利用

<link rel="stylesheet" href="xterm.css" /> <!—CSS必須 -->

<script src="xterm.js"></script>

参考

Page 21: Node.js with WebRTC DataChannel

xterm.jsでターミナルの準備

var container = document.getElementById('containerDiv'); // <div> Var term = null; function prepareTerminal() { term = new Terminal({ cols: 80, rows: 24, convertEol: true, //useStyle: true, //screenKeys: true, cursorBlink: true }); term.on('data', function(data) { dataChannel.send(data); // ユーザの入力をデータチャネルに送る }); term.on('title', function(title) { document.title = title; }); term.open(container); // ターミナルのUIを生成 }

参考

Page 22: Node.js with WebRTC DataChannel

xterm.jsで応答を表示

var dataChannel = peer.createDataChannel(

'channelName', dataOpt

);

// … 省略 …

dataChannel.onmessage = function (evt) {

term.write(evt.data);

// DataCannelで受け取ったデータをターミナルに表示

};

参考

Page 23: Node.js with WebRTC DataChannel

どうしてWebRTC DataChannelを使うの?

• sshで良いんじゃない? … ブラウザで色々やりたい

• WebSocketで良いんじゃない? – Node.js アプリが「外側」にあるときはOK

– では、Node.jsアプリもNATの「内側」にある時は??

Node.jsのアプリ WebSocket「サーバー」

Web ブラウザ

NAT

Node.js アプリ

Web ブラウザ

NAT NAT

Page 24: Node.js with WebRTC DataChannel

どうしてWebRTC DataChannelを使うの? • WebRTC DataChannel なら NAT越えの仕組みがある

– STUNサーバー – UDP ホールパンチング

• WiFiにプライバシーセパレーターがあっても通信可能

Node.js アプリ

Web ブラウザ

STUN サーバー

参考: • WebRTCハンズオン 概要編 - P2P通信行うまで(2-1):NAT越え https://goo.gl/FVYOkA • WebRTCの裏側にあるNATの話 - 答えの前にUDPホールパンチング https://goo.gl/P64kGX

NAT NAT

Page 25: Node.js with WebRTC DataChannel

どうしてWebRTC DataChannelを使うの?

• WebRTC DataChannel なら Firewall/Proxy越えの仕組みもある – TURN, TURN over TCP

• …が、いまのところNode.js アプリ側のFirewall越えが成功してません

Node.js アプリ

Web ブラウザ TURN サーバー

参考: • WebRTCハンズオン 概要編 - P2P通信行うまで(3):Firewall越え https://goo.gl/MJWxR9

Fire-wall

Proxy

Fire-wall

Proxy

Page 26: Node.js with WebRTC DataChannel

あれ? WebSocketでもできるのでは?

• WebSocketサーバーを外に立てればできる

Node.js + WebSocket クライアント

Web ブラウザ

WebSocket サーバー

Fire-wall

Proxy

Fire-wall

Proxy

WebRTC DataChannel との違い • DataChannelの場合、ネットワーク環境が許せば、P2Pで繋がる

→ レイテンシーが小さくなる • DataChannelの場合、End-to-End で暗号化される

⇔ WebSocketの場合、サーバで暗号解除される。悪意があれば、見たり改変したりできる

Page 27: Node.js with WebRTC DataChannel

Part 2 webrtc-native

Page 28: Node.js with WebRTC DataChannel

インストール方法

• Mac OS X 10.10.x 、 Xcode 7.x のケース – git clone https://github.com/vmolsa/webrtc-native

– cd webrtc-native

– export BUILD_WEBRTC=true

– npm install

• 注意 – npm install で非常に時間がかかる(数時間?)

• webrtcのソース取得、ビルドを実施するため

• proxyがある場合は、 ~/.boto ファイルに proxy設定が必要

• Ubuntu 16 でも同様の手順

Page 29: Node.js with WebRTC DataChannel

インストール方法(2)

• Mac OS X 10.11.x 、 Xcode 8.x のケース – git clone https://github.com/vmolsa/webrtc-native – cd webrtc-native – export BUILD_WEBRTC=true – npm install

• → libwebrtc のビルドに失敗

• 原因 – QTKit (QuickTime Kit) が見つからない、というエラー – Xcode 8 から QuickTime廃止、AVFoundationを利用 – Webrtc-native は Chromium 50 ベースでQTKitに依存

• Chromium 51〜 QTKit不要になっているが…

• 対策 – 最新Chromiumのソースを取得するようにビルドスクリプトを修正

• → 挫折

– Xcode 7.x でビルドした build/Release/webrtc.node をコピーしてくる • → なんとか動いた

Page 30: Node.js with WebRTC DataChannel

使い方 読み込み

// webrtc-native をインストールしたディレクトリで

var WebRTC = require('./');

var RTCPeerConnection = WebRTC.RTCPeerConnection;

var RTCIceCandidate= WebRTC.RTCIceCandidate;

var RTCSessionDescription = WebRTC.RTCSessionDescription;

var RTCDataChannel = WebRTC.RTCDataChannel;

// あとの使い方は、wrtcと同じ

Page 31: Node.js with WebRTC DataChannel

まとめ

• WebRTC は Webブラウザだけじゃない

• DataChannel なら Node.js からも使える

• NATの内側のNode.jsアプリにも接続できる

• Node.js で P2P アプリが作れる

–センサーデータの送受信?

– コンテンツ配信、ファイル共有?

–きっと、もっと楽しいことができるはず!

Page 32: Node.js with WebRTC DataChannel

Thank you!

@massie_g