オファー/アンサー メカニズムがアプリケーションに正しく実装されているかどうかを確認するために、2 つの単体テストを作成しました。最初の単体テストでは、オファーを受信したときのピアの動作を検証します。2 番目の単体テストでは、ピアがオファーを作成したときの動作を検証します。単体テストでは、次のモック オファーとモック アンサーを使用しました。
オファー :
var mockOffer { "sdp": "v=0\r\n" +
"o=- 7282588543017546346 2 IN IP4 127.0.0.1\r\n" +
"s=-\r\n" +
"t=0 0\r\n" +
"a=group:BUNDLE audio video\r\n" +
"a=msid-semantic: WMS\r\n" +
"m=audio 1 RTP/SAVPF 111 103 104 0 8 106 105 13 126\r\n" +
"c=IN IP4 0.0.0.0\r\n" +
"a=rtcp:1 IN IP4 0.0.0.0\r\n" +
"a=ice-ufrag:IJU9DHoiy8+X8FtX\r\n" +
"a=ice-pwd:3qgT9ydEM/CMkgan8ZWvgvbg\r\n" +
"a=ice-options:google-ice\r\n" +
"a=fingerprint:sha-256 54:90:7A:6F:BC:46:C4:5F:25:B9:02:97:3D:A7:53:5D:B4:F6:CE:55:EB:78:51:84:0C:41:0B:2B:21:AA:CD:05\r\n" +
"a=setup:actpass\r\n" +
"a=mid:audio\r\n" +
"a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n" +
"a=recvonly\r\n" +
"a=rtcp-mux\r\n" +
"a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:gC/fmSmErYS1MaaCQnXZRtKR6l8yWMc5zbOpdVT8\r\n" +
"a=rtpmap:111 opus/48000/2\r\n" +
"a=fmtp:111 minptime=10\r\n" +
"a=rtpmap:103 ISAC/16000\r\n" +
"a=rtpmap:104 ISAC/32000\r\n" +
"a=rtpmap:0 PCMU/8000\r\n" +
"a=rtpmap:8 PCMA/8000\r\n" +
"a=rtpmap:106 CN/32000\r\n" +
"a=rtpmap:105 CN/16000\r\n" +
"a=rtpmap:13 CN/8000\r\n" +
"a=rtpmap:126 telephone-event/8000\r\n" +
"a=maxptime:60\r\n" +
"m=video 1 RTP/SAVPF 100 116 117\r\n" +
"c=IN IP4 0.0.0.0\r\n" +
"a=rtcp:1 IN IP4 0.0.0.0\r\n" +
"a=ice-ufrag:IJU9DHoiy8+X8FtX\r\n" +
"a=ice-pwd:3qgT9ydEM/CMkgan8ZWvgvbg\r\n" +
"a=ice-options:google-ice\r\n" +
"a=fingerprint:sha-256 54:90:7A:6F:BC:46:C4:5F:25:B9:02:97:3D:A7:53:5D:B4:F6:CE:55:EB:78:51:84:0C:41:0B:2B:21:AA:CD:05\r\n" +
"a=setup:actpass\r\n" +
"a=mid:video\r\n" +
"a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\r\n" +
"a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n" +
"a=recvonly\r\n" +
"a=rtcp-mux\r\n" +
"a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:gC/fmSmErYS1MaaCQnXZRtKR6l8yWMc5zbOpdVT8\r\n" +
"a=rtpmap:100 VP8/90000\r\n" +
"a=rtcp-fb:100 ccm fir\r\n" +
"a=rtcp-fb:100 nack\r\n" +
"a=rtcp-fb:100 nack pli\r\n" +
"a=rtcp-fb:100 goog-remb\r\n" +
"a=rtpmap:116 red/90000\r\n" +
"a=rtpmap:117 ulpfec/90000\r\n",
"type":"offer"};
答え :
var mockAnswer = {"sdp":
"v=0\r\n" +
"o=- 6465573306213105510 2 IN IP4 127.0.0.1\r\n" +
"s=-\r\n" +
"t=0 0\r\n" +
"a=group:BUNDLE audio video\r\n" +
"a=msid-semantic: WMS\r\n" +
"m=audio 1 RTP/SAVPF 111 103 104 0 8 106 105 13 126\r\n" +
"c=IN IP4 0.0.0.0\r\n" +
"a=rtcp:1 IN IP4 0.0.0.0\r\n" +
"a=ice-ufrag:AyBahFUhrQOPtHlQ\r\n" +
"a=ice-pwd:QGUAtvpJDqYq2F8BUH2ZWdGv\r\n" +
"a=fingerprint:sha-256 54:90:7A:6F:BC:46:C4:5F:25:B9:02:97:3D:A7:53:5D:B4:F6:CE:55:EB:78:51:84:0C:41:0B:2B:21:AA:CD:05\r\n" +
"a=setup:active\r\n" +
"a=mid:audio\r\n" +
"a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n" +
"a=sendonly\r\n" +
"a=rtcp-mux\r\n" +
"a=rtpmap:111 opus/48000/2\r\n" +
"a=fmtp:111 minptime=10\r\n" +
"a=rtpmap:103 ISAC/16000\r\n" +
"a=rtpmap:104 ISAC/32000\r\n" +
"a=rtpmap:0 PCMU/8000\r\n" +
"a=rtpmap:8 PCMA/8000\r\n" +
"a=rtpmap:106 CN/32000\r\n" +
"a=rtpmap:105 CN/16000\r\n" +
"a=rtpmap:13 CN/8000\r\n" +
"a=rtpmap:126 telephone-event/8000\r\n" +
"a=maxptime:60\r\n" +
"m=video 1 RTP/SAVPF 100 116 117\r\n" +
"c=IN IP4 0.0.0.0\r\n" +
"a=rtcp:1 IN IP4 0.0.0.0\r\n" +
"a=ice-ufrag:AyBahFUhrQOPtHlQ\r\n" +
"a=ice-pwd:QGUAtvpJDqYq2F8BUH2ZWdGv\r\n" +
"a=fingerprint:sha-256 54:90:7A:6F:BC:46:C4:5F:25:B9:02:97:3D:A7:53:5D:B4:F6:CE:55:EB:78:51:84:0C:41:0B:2B:21:AA:CD:05\r\n" +
"a=setup:active\r\n" +
"a=mid:video\r\n" +
"a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\r\n" +
"a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n" +
"a=sendonly\r\n" +
"a=rtcp-mux\r\n" +
"a=rtpmap:100 VP8/90000\r\n" +
"a=rtcp-fb:100 ccm fir\r\n" +
"a=rtcp-fb:100 nack\r\n" +
"a=rtcp-fb:100 nack pli\r\n" +
"a=rtcp-fb:100 goog-remb\r\n" +
"a=rtpmap:116 red/90000\r\n" +
"a=rtpmap:117 ulpfec/90000\r\n",
"type": "answer"};
注 : これらは、createAnswer および createOffer メソッドを使用して生成されています。
- 最初の質問は、なぜ 2 つの指紋フィールドがあるのですか?
最初の単体テストは、ピアがリモート オファーを受信し、回答を返すシナリオを反映しています。オファーで setRemoteDescriptor を呼び出し、次に答えで serLocalDescriptor を呼び出します。このテストは問題なく動作し、エラーはスローされず、実行されたアクションに応じて SignallingState が変更されます (つまり、setRemoteDescriptor によって SignalingState が have-remote-offer などに変更されます)。
単体テスト :
it("Test the signalStatus machine when a peer receives an offer", function(done){
var peerReceiver = new app.PeerConnection("mock_receiver", session, false);
var successRemote = function(){
console.log("Remote descriptor installed successfully.");
expect(peerReceiver.getSignalingState()).toEqual("have-remote-offer");
peerReceiver._setLocalDescriptor(mockAnswer, successLocal, failure);
};
var successLocal = function(){
console.log("Local descriptor installed successfully.");
expect(peerReceiver.getSignalingState()).toEqual("stable");
done();
}.bind(this);
var failure = function(error){
console.log("Error installing SDP." + error);
expect(error).toBeNull();
done();
}.bind(this);
expect(peerReceiver.getSignalingState()).toEqual("none");
peerReceiver._setRemoteDescription(mockOffer, successRemote,failure);
});
2 番目の単体テストでは、同じモックの回答とオファーを使用しますが、ピアがローカル オファーを作成して設定し、リモート ピアから受信した回答をリモート オファーとして設定するシナリオを反映しています。テストは、オファーを指定して setLocalDescriptor を呼び出します。その結果、SIngnalingState は have-local-offer に変更されます。次に、mockAnswer を使用して setRemoteDescription が呼び出されます。この呼び出しにより、次のエラーが生成されます。
ERROR : Failed to set remote answer sdp: Failed to push down transport description: Failed to apply remote fingerprint.
原因は何ですか?私は何か間違ったことをしていますか?オファーとアンサーのフィンガープリントはまったく同じであり、フィンガープリントに問題がある場合は、最初の単体テストにも問題があるはずです。私は無知です。アドバイス、提案は大歓迎です。:D
単体テストの失敗:
it("Test the signalStatus machine when a peer sends an offer", function(done){
var peerSender = new app.PeerConnection("mock_sender", session, false);
var successRemote = function(){
console.log("Remote descriptor installed successfully.");
expect(peerSender.getSignalingState()).toEqual("stable");
done();
};
var successLocal = function(){
console.log("Local descriptor installed successfully.");
expect(peerSender.getSignalingState()).toEqual("have-local-offer");
peerSender._setRemoteDescription(mockAnswer, successRemote,failure);
}.bind(this);
var failure = function(error){
console.log("Error installing SDP." + error);
expect(error).toBeNull();
done();
}.bind(this);
expect(peerSender.getSignalingState()).toEqual("none");
peerSender._setLocalDescriptor(mockOffer, successLocal,failure);
});
エラーが生成された場合の RPCPeerConnection オブジェクト:
RTCPeerConnection {ondatachannel: null, oniceconnectionstatechange: function, onremovestream: function, onaddstream: function, onsignalingstatechange: function…}
iceConnectionState: "new"
iceGatheringState: "new"
localDescription: RTCSessionDescription
onaddstream: function (stream) { self.onRemoteStreamAdded(stream);}
ondatachannel: null
onicecandidate: function (e) { self.onIceCandidate(e, pc.iceGatheringState)}
oniceconnectionstatechange: function (e) { self.onIceConnectionStatusStateChange(e)}
onnegotiationneeded: null
onremovestream: function (stream) { self.onRemoteStreamRemoved(stream);}
onsignalingstatechange: function (e) {self.onSignalingStateChange(e)}
remoteDescription: null
signalingState: "have-local-offer"
__proto__: RTCPeerConnection
PeerConnection.js:287
Error installing SDP.undefined
ソースコード全体はここにあります
さらに情報が必要な場合はお知らせください。