我正在使用WebRTC数据通道在HTML5游戏中进行联网。 尽管可以使用WebRTC进行P2P,但该项目的拓扑结构是集中的客户端-服务器。该服务器是充当WebRTC对等方的Node.js进程。客户端是浏览器,使与该服务器1-1的连接。
我正在使用simple-peer库在客户端和服务器上处理WebRTC。在Node.js的服务器使用wrtc模块作为对等连接实例。 对于信令握手,我在客户端和服务器上都使用signalhub。
以下是一些伪造的代码,演示了如何设置握手
//client
var peer = new SimplePeer({initiator: true});
peer.on('signal', (signalPayload) => signalHub.broadcast('client_signal', signalPayload));
signalHub.subscribe('server_signal', function(signalPayload){ peer.signal(signalPayload) });
//server
signalHub.subscribe('client_signal', (signalPayload) => {
peer = new Simplepeer({});
peer.signal(signalPayload);
peer.on('signal', (signalPayload) => signalHub.broadcast('server_signal', signalPayload));
})
当前设置在Chrome中始终可以正常运行...
Firefox无法建立连接。简单的点对点的错误处理程序抛出一个错误
peer.on('error', (err) => {})
DOMException: "Failed to parse SDP: SDP Parse Error on line 6: No webrtc-datachannel token in m= media line, parse failed.
在特定信号的有效载荷触发该误差看起来像:
v=0
o=- 1575807233894551963 2 IN IP4 127.0.0.1
s=-
t=0 0
a=msid-semantic: WMS
m=application 0 UDP/DTLS/SCTP 5000
c=IN IP4 0.0.0.0
a=mid:0
a=sctpmap:5000 webrtc-datachannel 1024
这是服务器发送给客户端的有效负载,它是“答案”有效负载。
以下是铬的VS火狐一个完整的比较offer
和answer
有效载荷
{
type: "offer",
sdp:
"v=0
o=- 5121147169778109884 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE data
a=msid-semantic: WMS
m=application 9 DTLS/SCTP 5000
c=IN IP4 0.0.0.0
a=ice-ufrag:CmIA
a=ice-pwd:jHCWR4JJquU/r8KXtP0cQ9YN
a=ice-options:trickle
a=fingerprint:sha-256 0C:AC:DB:40:8E:AD:58:D8:09:3B:66:94:63:1B:00:D0:09:BD:F3:72:BF:29:66:53:94:9B:67:22:A9:27:A0:35
a=setup:actpass
a=mid:data
a=sctpmap:5000 webrtc-datachannel 1024
"
}
{
type: "offer",
sdp:
"v=0
o=mozilla...THIS_IS_SDPARTA-64.0.2 6450781105440687594 0 IN IP4 0.0.0.0
s=-
t=0 0
a=sendrecv
a=fingerprint:sha-256 54:5D:CF:E6:B6:B5:9B:60:C3:AB:F3:EC:5A:62:18:5E:13:F2:1A:23:86:03:BA:9D:D0:EA:67:7B:1C:5C:0A:2A\r\na=group:BUNDLE 0\r\na=ice-options:trickle
a=msid-semantic:WMS *
m=application 9 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 0.0.0.0
a=sendrecv
a=ice-pwd:c2217ee835bac1bdc0a765ebf1b5de2c
a=ice-ufrag:b0ceda3e
a=mid:0
a=setup:actpass
a=sctp-port:5000
a=max-message-size:1073741823"
}
"v=0
o=- 4547471447226747141 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE data
a=msid-semantic: WMS
m=application 62951 DTLS/SCTP 5000
c=IN IP4 192.168.1.159
b=AS:30
a=candidate:105744546 1 udp 2122260223 192.168.1.159 62951 typ host generation 0 network-id 1 network-cost 50
a=ice-ufrag:taPA
a=ice-pwd:Q/W3D4wgrRqMrfVT51yO3i5T
a=fingerprint:sha-256 2A:3C:A3:64:92:7D:32:F5:AB:5F:69:1F:C1:76:82:4C:97:A3:FE:CA:70:C5:E3:FA:FC:C0:11:FC:E3:DB:D5:1C
a=setup:active
a=mid:data
a=sctpmap:5000 webrtc-datachannel 1024"
"v=0
o=- 1575807233894551963 2 IN IP4 127.0.0.1
s=-
t=0 0
a=msid-semantic: WMS
m=application 0 UDP/DTLS/SCTP 5000
c=IN IP4 0.0.0.0
a=mid:0
a=sctpmap:5000 webrtc-datachannel 1024"
我们可以看到Firefox的答案有效载荷看起来很奇怪。它缺少fingerprint
和其他a=
字段。此外,它确实包含m=
字段,这很奇怪,它随后会抛出DOMException声明无法对其进行解析。
答案 0 :(得分:2)
您的服务器上的webrtc代码(设置中的远程端点)似乎不支持Firefox的报价使用较新的m=application
格式,并且在这种情况下产生了错误的答案,这使Firefox感到窒息继续,因为Firefox希望以新格式为其新格式的产品提供答案:
- Firefox报价:
m=application 9 UDP/DTLS/SCTP webrtc-datachannel a=sctp-port:5000
Firefox(63+)在这里使用的是2017年以来更新的version 21+ of the SCTP SDP draft。
Chrome使用的是自2013年以来较旧的version 05 of the SCTP SDP draft:
- Chrome优惠:
m=application 9 DTLS/SCTP 5000 a=sctpmap:5000 webrtc-datachannel 1024
不幸的是,这是一个重大变化。旧解析器希望在m行中找到一个数字(5000
),新解析器希望在其中找到webrtc-datachannel
。进一步了解here。
当Firefox作为回答者时,它会同时回答这两个问题(对旧报价的旧答案,对新报价的新答案),太好了!但是,当Firefox是要约人时(在这种情况下),它发出新的要约并期望得到新的答案(Chrome,BTW,即使它自己还没有发出,也知道如何回答新要约)。 / p>
理想情况下,您需要更新服务器以发出正确的答案。取而代之的是,如果将Firefox用作应答器,它应该可以工作。
如果不是这样,则可以在两种格式之间调整SDP:您需要在服务器看到Firefox之前将Firefox的报价更改为旧格式,并在设置之前将其答案恢复为新格式。在Firefox中使用 setRemoteDescription 。
答案 1 :(得分:2)
根据问题下方的评论,我认为现在wrtc
节点模块不理解较新版本的Firefox使用的新SCTP SDP格式。要固定的WRTC模块需要则和更新。
我看到您已经打开https://github.com/node-webrtc/node-webrtc/issues/483。我认为这是办法让这个固定/工作。
答案 2 :(得分:0)
得到的Chrome这样的答案的唯一方法是,如果你使用其专有的RTP datachannel这样的:
var pc = new RTCPeerConnection(null, {optional: [{RtpDataChannels: true}]});
pc.setRemoteDescription({type: 'offer', sdp: 'v=0\no=mozilla...THIS_IS_SDPARTA-64.0.2 6450781105440687594 0 IN IP4 0.0.0.0\ns=-\nt=0 0\na=sendrecv\na=fingerprint:sha-256 54:5D:CF:E6:B6:B5:9B:60:C3:AB:F3:EC:5A:62:18:5E:13:F2:1A:23:86:03:BA:9D:D0:EA:67:7B:1C:5C:0A:2A\r\na=group:BUNDLE 0\r\na=ice-options:trickle\na=msid-semantic:WMS *\nm=application 9 UDP/DTLS/SCTP webrtc-datachannel\nc=IN IP4 0.0.0.0\na=sendrecv\na=ice-pwd:c2217ee835bac1bdc0a765ebf1b5de2c\na=ice-ufrag:b0ceda3e\na=mid:0\na=setup:actpass\na=sctp-port:5000\na=max-message-size:1073741823\n'})
其次是createAnswer。
不要这样做。 rtp数据通道在所有方面均低于标准数据通道。不要使用它。