3

オファー/アンサー メカニズムがアプリケーションに正しく実装されているかどうかを確認するために、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 

ソースコード全体はここにあります

さらに情報が必要な場合はお知らせください。

4

0 に答える 0