@rtcio/react
Version:
A wrapper around the @rtcio/core library for React integration
91 lines • 3.92 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import { RTC, } from "@rtcio/core";
import { createContext, useEffect, useMemo, useRef, useState, } from "react";
import { option } from "@dbidwell94/ts-utils";
export const p2pContext = createContext(null);
export default function P2PProvider({ roomName, signaler, children, dataTimeoutMs, iceServers, maxChunkSizeBytes, pollSignalerInterval, }) {
const memoSignaler = useMemo(() => signaler, []);
const memoIce = useMemo(() => iceServers, []);
const memoDataTimeout = useMemo(() => dataTimeoutMs, []);
const memoDataSize = useMemo(() => maxChunkSizeBytes, []);
const peers = useRef(new Map());
const signalerPeers = useRef(new Set());
const [signalPeersUpdated, setSignalPeersUpdated] = useState(false);
const [peerIds, setPeerIds] = useState([]);
const [rtc, setRtc] = useState(option.none());
useEffect(() => {
if (rtc.isNone())
return;
const { rtc: manager } = rtc.value;
let interval = option.none();
const onPeersHandler = new AbortController();
if (pollSignalerInterval) {
interval = option.some(setInterval(() => {
const roomPeers = new Set(manager.getRoomPeers());
let peersUpdated = false;
// first, check to see if a new peer joined
for (const peerId of roomPeers) {
if (!signalerPeers.current.has(peerId)) {
signalerPeers.current.add(peerId);
peersUpdated = true;
}
}
// now check to see if a peer disconnected
for (const peerId of signalerPeers.current) {
if (!roomPeers.has(peerId)) {
peersUpdated = true;
signalerPeers.current.delete(peerId);
}
}
if (peersUpdated) {
setSignalPeersUpdated((val) => !val);
}
}, pollSignalerInterval));
}
else {
manager.on("signalPeerConnected", (newPeer) => {
signalerPeers.current.add(newPeer);
setSignalPeersUpdated((val) => !val);
}, onPeersHandler.signal);
manager.on("signalPeerDisconnected", (peerId) => {
signalerPeers.current.delete(peerId);
setSignalPeersUpdated((val) => !val);
}, onPeersHandler.signal);
}
return () => {
interval.inspect((handle) => clearTimeout(handle));
onPeersHandler.abort();
};
}, [pollSignalerInterval, rtc]);
useEffect(() => {
const rtcInstance = new RTC({
roomName,
signaler: memoSignaler,
dataTimeoutMs: memoDataTimeout,
iceServers: memoIce,
maxChunkSizeBytes: memoDataSize,
});
rtcInstance.connectToRoom().then((res) => {
if (res.isError()) {
return;
}
rtcInstance.on("connected", (peer) => {
peers.current.set(peer.id, peer);
setPeerIds((current) => [...current, peer.id]);
peer.on("connectionClosed", (peerId) => {
setPeerIds((current) => current.filter((id) => id !== peerId));
peers.current.delete(peerId);
});
});
setRtc(option.some({ rtc: rtcInstance, myId: res.value }));
});
return () => {
rtcInstance.close();
};
}, [roomName]);
const memoSignalPeers = useMemo(() => {
return Array.from(signalerPeers.current);
}, [signalPeersUpdated]);
return (_jsx(p2pContext.Provider, { value: { rtc, peerIds, peers, signalerPeers: memoSignalPeers }, children: children }));
}
//# sourceMappingURL=Provider.js.map