WebRTC RTCDataChannel无0.5秒休眠触发InvalidStateError求助
WebRTC DataChannel 发送失败问题排查
我基于WebRTC API开发了一个最简可运行测试页面,包含WebRTC_test.html及关联JS文件。当前问题是该代码必须依赖datachannel.js第20行的0.5秒休眠逻辑,若将其注释,会触发以下错误:
Uncaught InvalidStateError: Failed to execute 'send' on 'RTCDataChannel': RTCDataChannel.readyState is not 'open' at datachannel.js:21:1
相关代码
WebRTC_test.html
<!doctype html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>WebRTC test</title> <script type="module" src="datachannel.js"></script> </head> <body> <h1>WebRTC test</h1> <input id="inputmessage" type="text" placeholder="message" /> <button id="buttonsend" onclick="buttonsendclick()">send</button> <div id="messagelog"></div> </body> </html>
datachannel.js
// WebRTC import { pcOffInit } from "./offer.js"; import { pcAnsInit, addDatachannelListenerAns } from "./answer.js"; export const configuration = { iceServers: [{ urls: "stun:stun.stunprotocol.org" }], }; console.log("===1 pc1 configuration", configuration); export const webrtc = { dc: {}, // implement datachannel as an object member to allow updates from modules }; await pcOffInit(); // intitiate offering RTCPeerConnection await pcAnsInit(); // intitiate answering RTCPeerConnection addDatachannelListenerAns(); // If the following sleep is commented out, receive error - // Uncaught InvalidStateError: Failed to execute 'send' on 'RTCDataChannel': RTCDataChannel.readyState is not 'open' at datachannel.js:21:1 await new Promise((r) => setTimeout(r, 500)); // sleep webrtc.dc.send("message sent from datachannel.js"); console.log("===8.5 message sent from answer.js"); const buttonsendclick = () => { const message = document.getElementById("inputmessage").value; webrtc.dc.send(message); console.log("===11 inputmessage: ", message); }; window.buttonsendclick = buttonsendclick; //allow access from HTML
offer.js
// Offering peer connection import { webrtc, configuration } from "./datachannel.js"; import { getAnswer, setRemoteDescriptionAns } from "./answer.js"; let pcOff; // offering RTCPeerConnection const icecandidatefn = async (event) => { if (event.candidate !== null) { console.log("===5 pcOff event.candidate", event.candidate); } else { console.log("===6 pcOff all ice candidates"); setRemoteDescriptionAns(pcOff.localDescription); pcOff.setRemoteDescription(await getAnswer()); } }; export const pcOffInit = async () => { try { pcOff = new RTCPeerConnection(configuration); console.log("===2 pcOff: ", pcOff); console.log("===2.5 pcOff.connectionState: ", pcOff.connectionState); } catch (err) { console.log("error: " + err); } webrtc.dc = pcOff.createDataChannel("chat"); console.log("===3 webrtc.dc: ", webrtc.dc); pcOff.setLocalDescription(await pcOff.createOffer()); console.log("===4 pcOff.localDescription: ", pcOff.localDescription); pcOff.addEventListener("icecandidate", icecandidatefn); webrtc.dc.addEventListener("open", (event) => { console.log("===9 pcOff event: ", event); }); webrtc.dc.addEventListener("message", (message) => { const messagelog = document.getElementById("messagelog"); messagelog.innerHTML += message.data; messagelog.innerHTML += "<br />"; console.log("===10 dc message received: ", message.data); }); };
answer.js
// Answering peer connection import { webrtc, configuration } from "./datachannel.js"; let pcAns; // answering RTCPeerConnection export const pcAnsInit = async () => { try { pcAns = new RTCPeerConnection(configuration); console.log("===4.5 pcAns: ", pcAns); } catch (err) { console.log("error: " + err); } }; export const getAnswer = async () => { const answer = await pcAns.createAnswer(); console.log("===7 getAnswer(): ", answer); pcAns.setLocalDescription(answer); return answer; }; const datachannelfn = (event) => { console.log("===7.5 webrtc.dc.readyState: ", webrtc.dc.readyState); console.log("===7.5 pcAns.connectionState: ", pcAns.connectionState); webrtc.dc = event.channel; console.log("===8 webrtc.dc: ", event.channel); webrtc.dc.send("message sent from answer.js"); console.log("===8.5 message sent from answer.js"); }; export const setRemoteDescriptionAns = (offer) => { pcAns.setRemoteDescription(offer); console.log("===7 offer: ", offer); console.log("===8 pcAns: ", pcAns); }; export const addDatachannelListenerAns = () => { pcAns.addEventListener("datachannel", datachannelfn); };
内容的提问来源于stack exchange,提问作者user2309803
相关产品推荐
相关产品推荐

