feat: add data channel to webrtc connection

This commit is contained in:
Fritz Heiden 2025-04-14 13:59:59 +02:00
parent 6cefa7392c
commit 6940782024
2 changed files with 37 additions and 3 deletions

View File

@ -8,10 +8,12 @@ function WebRTCService() {
const STATE_CLOSED = "closed";
const STATE_FAILED = "failed";
const ICE_CONNECTION_STATE_CHANGE_EVENT = "iceconnectionstatechange";
const DATA_CHANNEL_OPEN_EVENT = "datachannelopen";
let videoElement;
let peerConnection;
let peerId;
let dataChannel;
let eventEmitter = new EventEmitter();
@ -57,12 +59,19 @@ function WebRTCService() {
console.log("Negotiation needed");
negotiate(targetId);
};
dataChannel = peerConnection.createDataChannel("data");
dataChannel.addEventListener("open", () => {
eventEmitter.dispatchEvent(DATA_CHANNEL_OPEN_EVENT);
});
negotiate(targetId);
}
function disconnect() {
peerConnection.close();
eventEmitter.dispatchEvent(ICE_CONNECTION_STATE_CHANGE_EVENT, peerConnection.iceConnectionState);
eventEmitter.dispatchEvent(
ICE_CONNECTION_STATE_CHANGE_EVENT,
peerConnection.iceConnectionState
);
}
async function negotiate(targetId) {
@ -125,12 +134,27 @@ function WebRTCService() {
peerConnection.addIceCandidate(iceCandidate);
}
function sendDataString(data) {
if (!dataChannel) return;
if (dataChannel.readyState !== "open") return;
dataChannel.send(data);
}
function sendDataJson(data) {
let dataJson = JSON.stringify(data);
sendDataString(dataJson);
}
function onStateChanged(callback) {
eventEmitter.on(ICE_CONNECTION_STATE_CHANGE_EVENT, () => {
callback(peerConnection.iceConnectionState);
});
}
function onDataChannelOpen(callback) {
eventEmitter.on(DATA_CHANNEL_OPEN_EVENT, callback);
}
function getConfiguration() {
return {
iceServers: [{ urls: "stun:stun.l.google.com:19302" }],
@ -155,7 +179,10 @@ function WebRTCService() {
disconnect,
setVideoElement,
getVideoElement,
sendDataString,
sendDataJson,
onStateChanged,
onDataChannelOpen,
};
}

View File

@ -22,6 +22,7 @@ function IntegrationView(props) {
connectionState() === WebRTCService.STATE_CLOSED
);
WebRTCService.onStateChanged(handleConnectionStateChanged);
WebRTCService.onDataChannelOpen(handleDataChannelOpen);
let videoElement = null;
createEffect(() => {
@ -40,7 +41,7 @@ function IntegrationView(props) {
async function setIntegrationFromUrl() {
let integrationId = UrlUtils.getQueryParameter("id");
if (!integrationId) return;
let integration = await DeviceService.getIntegration(integrationId)
let integration = await DeviceService.getIntegration(integrationId);
setIntegration(integration);
}
@ -58,6 +59,12 @@ function IntegrationView(props) {
setConnectionState(state);
}
function handleDataChannelOpen() {
setInterval(() => {
WebRTCService.sendDataJson({ message: "ping" });
}, 1000);
}
return (
<div
class={