![](/img/trans.png)
[英]WebRTC peer connection does not establish on Safari, does in Chrome, Firefox
[英]Unable to establish WebRTC connection with Node JS server as a peer
我正在嘗試使用 WebRTC 數據通道將從 canvas 捕獲的圖像發送到我的 NodeJS 后端服務器。 那就是我試圖讓我的服務器成為對等點。 但由於某種原因,我無法建立連接。
async function initChannel()
{
const offer = await peer.createOffer();
await peer.setLocalDescription(offer);
const response = await fetch("/connect", {
headers: {
'Content-Type': 'application/json',
},
method: 'post',
body: JSON.stringify({ sdp: offer, id: Math.random() })
}).then((res) => res.json());
peer.setRemoteDescription(response.sdp);
const imageChannel = peer.createDataChannel("imageChannel", { ordered: false, maxPacketLifeTime: 100 });
peer.addEventListener("icecandidate", console.log);
peer.addEventListener("icegatheringstatechange",console.log);
// drawCanvas function draws images got from the server.
imageChannel.addEventListener("message", message => drawCanvas(remoteCanvasCtx, message.data, imageChannel));
// captureImage function captures and sends image to server using imageChannel.send()
imageChannel.addEventListener("open", () => captureImage(recordCanvasCtx, recordCanvas, imageChannel));
}
const peer = new RTCPeerConnection({ iceServers: [{ urls: "stun:stun.stunprotocol.org:3478" }] });
initChannel();
這里captureImage
和drawCanvas
都沒有被調用。
import webrtc from "wrtc"; // The wrtc module ( npm i wrtc )
function handleChannel(channel)
{
console.log(channel.label); // This function is not being called.
}
app.use(express.static(resolve(__dirname, "public")))
.use(bodyParser.json())
.use(bodyParser.urlencoded({ extended: true }));
app.post("/connect", async ({ body }, res) =>
{
console.log("Connecting to client...");
let answer, id = body.id;
const peer = new webrtc.RTCPeerConnection({ iceServers: [{ urls: "stun:stun.stunprotocol.org:3478" }] });
await peer.setRemoteDescription(new webrtc.RTCSessionDescription(body.sdp));
await peer.setLocalDescription(answer = await peer.createAnswer());
peer.addEventListener("datachannel",handleChannel)
return res.json({ sdp: answer });
});
app.listen(process.env.PORT || 2000);
這里 post 請求處理得很好,但從不調用handleChannel
。
當我運行它時,我沒有收到任何錯誤,但是當我檢查連接狀態時,它永遠顯示“新”。 我控制台記錄了遠程和本地描述,它們似乎都設置好了。 我在這里做錯了什么?
我對 WebRTC 很陌生,我什至不確定這是否是從服務器連續發送圖像(用戶網絡攝像頭的幀)和返回的正確方法,如果有人能告訴我更好的方法,請這樣做。
還有一件事,我如何通過數據通道以低延遲發送圖像 blob(從canvas.toBlob()
獲得)。
在我朋友的幫助下,我終於想通了。 問題是我必須在調用peer.createOffer()
之前創建 DataChannel 。 peer.onnegotiationneeded
回調僅在創建通道后調用。 通常,當您通過將 stream 傳遞給 WebRTC 來創建媒體通道(音頻或視頻)時,通常會發生這種情況,但由於我不使用它們,所以我必須這樣做。
const peer = new RTCPeerConnection({ iceServers: [{ urls: "stun:stun.l.google.com:19302" }] });
const imageChannel = peer.createDataChannel("imageChannel");
imageChannel.onmessage = ({ data }) =>
{
// Do something with received data.
};
imageChannel.onopen = () => imageChannel.send(imageData);// Data channel opened, start sending data.
peer.onnegotiationneeded = initChannel
async function initChannel()
{
const offer = await peer.createOffer();
await peer.setLocalDescription(offer);
// Send offer and fetch answer from the server
const { sdp } = await fetch("/connect", {
headers: {
"Content-Type": "application/json",
},
method: "post",
body: JSON.stringify({ sdp: peer.localDescription }),
})
.then(res => res.json());
peer.setRemoteDescription(new RTCSessionDescription(sdp));
}
接收客戶通過 post 請求發送的報價。 為它創建一個答案並作為響應發送。
app.post('/connect', async ({ body }, res) =>
{
const peer = new webrtc.RTCPeerConnection({
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }],
});
console.log('Connecting to client...');
peer.ondatachannel = handleChannel;
await peer.setRemoteDescription(new webrtc.RTCSessionDescription(body.sdp));
await peer.setLocalDescription(await peer.createAnswer());
return res.json({ sdp: peer.localDescription });
});
function 處理數據通道。
/**
* This function is called once a data channel is ready.
*
* @param {{ type: 'datachannel', channel: RTCDataChannel }} event
*/
function handleChannel({ channel })
{
channel.addEventListener("message", {data} =>
{
// Do something with data received from client.
});
// Can use the channel to send data to client.
channel.send("Hi from server");
}
所以這就是發生的事情:
onnegotiationneeded
回調。ondatachannel
回調。我在這里使用了發布請求來交換報價和答案,但是如果您喜歡的話,使用 Web 套接字應該很容易做到這一點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.