WebRTCのRTCDataChannel APIを使って、複数人にデータを送信してみる
WebRTCで複数人接続してみるの続きです。今回は「RTCDataChannel API」を使って、データの送受信を試してみたいと思います。
複数人接続の記事の後なので、複数人に対してデータの送受信までを試してみます。
RTCDataChannel APIとは?
Peerの接続を利用して、データを送受信できる仕組み。・送受信できるデータ形式
Blob、ArrayBuffer、ArrayBufferViewのようなデータ形式をサポート。
・通信プロトコル
UDP、TCP、SCTPをサポート。
RTCDataChannel APIを使うには?
こんな感じで生成することができます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 端末A側のpeerを生成 | |
var peer = new webkitRTCPeerConnection({ | |
"iceServers": [{"url": "stun:stun.l.google.com:19302"}] | |
}); | |
// 端末A側のdataChannelを生成(dataChannelOptionは省略可能 | |
// オプションに関してはこちらの記事が詳しいです。 | |
// http://www.html5rocks.com/ja/tutorials/webrtc/datachannels/ | |
var dataChannelLabel = "test channel"; | |
var dataChannelOption = {}; | |
var dataChannel = peer.createDataChannel(dataChannelLabel, dataChannelOption); | |
dataChannel.onerror = function (error) { | |
// エラー時に動作 | |
console.log(error); | |
}; | |
dataChannel.onmessage = function (event) { | |
// Peer接続している端末から、send()された時に動作 | |
console.log(event.currentTarget.label); | |
console.log("data channel message:", event.data); | |
}; | |
dataChannel.onopen = function () { | |
// dataChannelの接続確立時に動作 | |
console.log("data channel opened"); | |
}; | |
dataChannel.onclose = function () { | |
// dataChannelの切断時に動作 | |
console.log("data channel closed"); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ondatachannelで、 | |
// 端末B側のdataChannel(event.channel)を取得できるので保持しておく | |
// createAnswerのコールバックのタイミングでもオッケイ。 | |
var remoteDataChannel = null; | |
peer.ondatachannel = function(event) { | |
remoteDataChannel = event.channel; | |
}; |
下記をconsoleから実行すると端末B側の「dataChannel.onmessage」が動作します。
remoteDataChannel.send("test test");
注意点ですが、Peerでの接続確立後に「peer.createDataChannel」をしても相手側の「peer.ondatachannel」は動作しませんでした。
オファー前に「peer.createDataChannel」をしとくと良いようです。
参考:http://blog.wnotes.net/blog/article/beginning-webrtc-datachannel
前回のソース(WebRTCで複数人接続してみる)を修正してみる
webrtc.jsを修正する・initの処理を変更(this.dataChannelsとthis.remoteDataChannelsを初期化させる処理追加
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 初期化 | |
* @param {Object} option { | |
* videoElementId: "", | |
* iceCandidateCallback: function() {}, | |
* dataChannels: [{ | |
* label: 'test channel', | |
* option: { | |
* ordered: false, // 順序を保証しない | |
* maxRetransmitTime: 3000, // ミリ秒 | |
* }, | |
* onmessageCallback: function() { | |
* console.log("test channel received!!"); | |
* } | |
* }] | |
* } | |
*/ | |
init: function(option) { | |
this.option = option; | |
this.peer = null; | |
this.localStream = null; | |
this.isStartVideo = false; | |
this.dataChannels = {}; | |
this.remoteDataChannels = {}; | |
}, |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* コネクションをはる | |
* @return {Boolean} true: RTCPeerConnectionが生成済み, false: 生成できなかった | |
*/ | |
connect: function() { | |
if (this.peer) { | |
return true; | |
} | |
if (!this.localStream) { | |
return false; | |
} | |
if (!this.option.videoElementId) { | |
return false; | |
} | |
this.peer = this.createPeer(); | |
if (this.option.dataChannels && this.option.dataChannels.length > 0) {// Data Channelの設定があれば接続させる | |
for (var i = 0, l = this.option.dataChannels.length; i < l; i++) { | |
var dataChannelOption = this.option.dataChannels[i]; | |
this.createDataChannel(dataChannelOption.label, dataChannelOption.option, dataChannelOption.onmessageCallback); | |
} | |
this.peer.ondatachannel = (function(event) { | |
this.remoteDataChannels[event.channel.label] = event.channel; | |
}.bind(this)); | |
} | |
this.peer.addStream(this.localStream); | |
var iceCandidateCallback = this.option.iceCandidateCallback; | |
this.peer.onicecandidate = function(event) { | |
iceCandidateCallback && iceCandidateCallback(event.candidate); | |
}; | |
var videoElementId = this.option.videoElementId; | |
this.peer.onaddstream = function(event) { | |
var video = document.getElementById(videoElementId); | |
video.src = window.webkitURL.createObjectURL(event.stream); | |
}; | |
return true; | |
}, |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Data Channelの生成 | |
* @param {String} label | |
* @param {Object} option | |
* @param {Function} onmessageCallback | |
*/ | |
createDataChannel: function(label, option, onmessageCallback) { | |
var dataChannel = this.peer.createDataChannel(label, option); | |
dataChannel.onerror = function (error) { | |
console.log(error); | |
}; | |
dataChannel.onmessage = function (event) { | |
console.log(event.currentTarget.label); | |
console.log("data channel message:", event.data); | |
onmessageCallback && onmessageCallback(); | |
}; | |
dataChannel.onopen = function () { | |
console.log("data channel opened"); | |
}; | |
dataChannel.onclose = function () { | |
console.log("data channel closed"); | |
}; | |
this.dataChannels[label] = dataChannel; | |
}, |
・createWebrtcInstanceの処理を変更(new するところに、dataChannelsを追加しただけ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// WebRTCのインスタンスを生成する | |
// @param {String} id | |
// @return {Object} WebRTCインスタンス | |
createWebrtcInstance: function(id) { | |
var videoElementId = this.getVideoElementId(id); | |
var video = document.createElement('video'); | |
video.id = videoElementId; | |
video.autoplay = true; | |
document.getElementsByTagName('body')[0].appendChild(video); | |
return new Webrtc({ | |
videoElementId: videoElementId, | |
iceCandidateCallback: (function(candidate) { | |
this.sendMessage(this.messageTypes.candidate, {sendto: id, fromUserId: this.userId, candidate: candidate}); | |
}.bind(this)), | |
dataChannels: [{ | |
label: 'test channel', | |
option: { | |
ordered: false, // 順序を保証しない | |
maxRetransmitTime: 3000, // ミリ秒 | |
}, | |
onmessageCallback: function() { | |
console.log("test channel received!!"); | |
} | |
}] | |
}); | |
}, |
データ送受信の実行手順
1. WebRTCで複数人接続してみるの「作ってみた」の手順通り実施し、複数人接続をさせておく2. 全てのブラウザでDeveloper Toolsを開く
3. どれか1つでconsoleから下記を実行する
for (var i in webrtcTest.webRtcInstances) {4. 実行したタブ以外で、下記のようなメッセージがconsole上に流れていることを確認できる
if (i !== webrtcTest.localInstanceKey) {
webrtcTest.webRtcInstances[i].remoteDataChannels['test channel'].send("test dayo");
}
}
data channel message:test dayoできた!!
(個別に送信したい場合は、下記を実行する
webrtcTest.webRtcInstances[id].remoteDataChannels['test channel'].send("test dayo");※ idは送信したい端末のid
終わりに
ここまでやったらWebRTCはお腹いっぱい気味。つぎは、ファイルの送受信をできるようにするかなあ。。
(チャンクさせるようにするなんて面倒だ。。
まあ、そこまでやるならサービスレベルのものを作るときかなー。
あとは、peer.jsとかライブラリを使ってみるとか。
気が向いたらやります。
参考
・WebRTC data channelshttp://www.html5rocks.com/ja/tutorials/webrtc/datachannels/
・WebRTC-DataChannel使ってみたよ
http://blog.wnotes.net/blog/article/beginning-webrtc-datachannel
以上!
登録:
コメントの投稿
(
Atom
)
0 件のコメント :
コメントを投稿