Refactored useSession to properly handle peer events
Added indicator of what connection errored
This commit is contained in:
parent
aed9c06dc6
commit
da0f80316c
@ -21,45 +21,96 @@ function useSession(
|
|||||||
|
|
||||||
const [peers, setPeers] = useState({});
|
const [peers, setPeers] = useState({});
|
||||||
|
|
||||||
|
// Setup event listeners for peers
|
||||||
|
useEffect(() => {
|
||||||
|
let peerEvents = [];
|
||||||
|
for (let peer of Object.values(peers)) {
|
||||||
|
function handleSignal(signal) {
|
||||||
|
socket.emit("signal", JSON.stringify({ to: peer.id, signal }));
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleConnect() {
|
||||||
|
onPeerConnected && onPeerConnected(peer);
|
||||||
|
if (peer.sync) {
|
||||||
|
peer.connection.send({ id: "sync" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDataComplete(data) {
|
||||||
|
onPeerData && onPeerData({ peer, data });
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleTrack(track, stream) {
|
||||||
|
onPeerTrackAdded && onPeerTrackAdded({ peer, track, stream });
|
||||||
|
track.addEventListener("mute", () => {
|
||||||
|
onPeerTrackRemoved && onPeerTrackRemoved({ peer, track, stream });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleClose() {
|
||||||
|
onPeerDisconnected && onPeerDisconnected(peer);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleError(error) {
|
||||||
|
onPeerError && onPeerError({ peer, error });
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
peer.connection.on("signal", handleSignal);
|
||||||
|
peer.connection.on("connect", handleConnect);
|
||||||
|
peer.connection.on("dataComplete", handleDataComplete);
|
||||||
|
peer.connection.on("track", handleTrack);
|
||||||
|
peer.connection.on("close", handleClose);
|
||||||
|
peer.connection.on("error", handleError);
|
||||||
|
// Save events for cleanup
|
||||||
|
peerEvents.push({
|
||||||
|
peer,
|
||||||
|
handleSignal,
|
||||||
|
handleConnect,
|
||||||
|
handleDataComplete,
|
||||||
|
handleTrack,
|
||||||
|
handleClose,
|
||||||
|
handleError,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup events
|
||||||
|
return () => {
|
||||||
|
for (let {
|
||||||
|
peer,
|
||||||
|
handleSignal,
|
||||||
|
handleConnect,
|
||||||
|
handleDataComplete,
|
||||||
|
handleTrack,
|
||||||
|
handleClose,
|
||||||
|
handleError,
|
||||||
|
} of peerEvents) {
|
||||||
|
peer.connection.off("signal", handleSignal);
|
||||||
|
peer.connection.off("connect", handleConnect);
|
||||||
|
peer.connection.off("dataComplete", handleDataComplete);
|
||||||
|
peer.connection.off("track", handleTrack);
|
||||||
|
peer.connection.off("close", handleClose);
|
||||||
|
peer.connection.off("error", handleError);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [
|
||||||
|
peers,
|
||||||
|
onPeerConnected,
|
||||||
|
onPeerDisconnected,
|
||||||
|
onPeerData,
|
||||||
|
onPeerTrackAdded,
|
||||||
|
onPeerTrackRemoved,
|
||||||
|
onPeerError,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Setup event listeners for the socket
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
function addPeer(id, initiator, sync) {
|
function addPeer(id, initiator, sync) {
|
||||||
const peer = new Peer({ initiator, trickle: false });
|
const connection = new Peer({ initiator, trickle: false });
|
||||||
|
|
||||||
peer.on("signal", (signal) => {
|
|
||||||
socket.emit("signal", JSON.stringify({ to: id, signal }));
|
|
||||||
});
|
|
||||||
|
|
||||||
peer.on("connect", () => {
|
|
||||||
onPeerConnected && onPeerConnected({ id, peer, initiator });
|
|
||||||
if (sync) {
|
|
||||||
peer.send({ id: "sync" });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
peer.on("dataComplete", (data) => {
|
|
||||||
onPeerData && onPeerData({ id, peer, data });
|
|
||||||
});
|
|
||||||
|
|
||||||
peer.on("track", (track, stream) => {
|
|
||||||
onPeerTrackAdded && onPeerTrackAdded({ id, peer, track, stream });
|
|
||||||
track.addEventListener("mute", () => {
|
|
||||||
onPeerTrackRemoved && onPeerTrackRemoved({ id, peer, track, stream });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
peer.on("close", () => {
|
|
||||||
onPeerDisconnected && onPeerDisconnected(id);
|
|
||||||
});
|
|
||||||
|
|
||||||
peer.on("error", (error) => {
|
|
||||||
onPeerDisconnected && onPeerDisconnected(id);
|
|
||||||
onPeerError && onPeerError(error);
|
|
||||||
console.error(error);
|
|
||||||
});
|
|
||||||
|
|
||||||
setPeers((prevPeers) => ({
|
setPeers((prevPeers) => ({
|
||||||
...prevPeers,
|
...prevPeers,
|
||||||
[id]: peer,
|
[id]: { id, connection, initiator, sync },
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +120,7 @@ function useSession(
|
|||||||
|
|
||||||
function handlePartyMemberLeft(id) {
|
function handlePartyMemberLeft(id) {
|
||||||
if (id in peers) {
|
if (id in peers) {
|
||||||
peers[id].destroy();
|
peers[id].connection.destroy();
|
||||||
}
|
}
|
||||||
setPeers((prevPeers) => omit(prevPeers, [id]));
|
setPeers((prevPeers) => omit(prevPeers, [id]));
|
||||||
}
|
}
|
||||||
@ -85,7 +136,7 @@ function useSession(
|
|||||||
function handleSignal(data) {
|
function handleSignal(data) {
|
||||||
const { from, signal } = JSON.parse(data);
|
const { from, signal } = JSON.parse(data);
|
||||||
if (from in peers) {
|
if (from in peers) {
|
||||||
peers[from].signal(signal);
|
peers[from].connection.signal(signal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,15 +150,7 @@ function useSession(
|
|||||||
socket.removeListener("joined party", handleJoinedParty);
|
socket.removeListener("joined party", handleJoinedParty);
|
||||||
socket.removeListener("signal", handleSignal);
|
socket.removeListener("signal", handleSignal);
|
||||||
};
|
};
|
||||||
}, [
|
}, [peers]);
|
||||||
peers,
|
|
||||||
onPeerConnected,
|
|
||||||
onPeerDisconnected,
|
|
||||||
onPeerData,
|
|
||||||
onPeerTrackAdded,
|
|
||||||
onPeerTrackRemoved,
|
|
||||||
onPeerError,
|
|
||||||
]);
|
|
||||||
|
|
||||||
return { peers, socket };
|
return { peers, socket };
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ function Game() {
|
|||||||
mapDataRef.current = mapData;
|
mapDataRef.current = mapData;
|
||||||
setMapSource(mapSource);
|
setMapSource(mapSource);
|
||||||
for (let peer of Object.values(peers)) {
|
for (let peer of Object.values(peers)) {
|
||||||
peer.send({ id: "map", data: mapDataRef.current });
|
peer.connection.send({ id: "map", data: mapDataRef.current });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ function Game() {
|
|||||||
}));
|
}));
|
||||||
for (let peer of Object.values(peers)) {
|
for (let peer of Object.values(peers)) {
|
||||||
const data = { [token.id]: token };
|
const data = { [token.id]: token };
|
||||||
peer.send({ id: "tokenEdit", data });
|
peer.connection.send({ id: "tokenEdit", data });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ function Game() {
|
|||||||
});
|
});
|
||||||
for (let peer of Object.values(peers)) {
|
for (let peer of Object.values(peers)) {
|
||||||
const data = { [token.id]: token };
|
const data = { [token.id]: token };
|
||||||
peer.send({ id: "tokenRemove", data });
|
peer.connection.send({ id: "tokenRemove", data });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,26 +70,26 @@ function Game() {
|
|||||||
setNickname(nickname);
|
setNickname(nickname);
|
||||||
for (let peer of Object.values(peers)) {
|
for (let peer of Object.values(peers)) {
|
||||||
const data = { [socket.id]: nickname };
|
const data = { [socket.id]: nickname };
|
||||||
peer.send({ id: "nickname", data });
|
peer.connection.send({ id: "nickname", data });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const [stream, setStream] = useState(null);
|
const [stream, setStream] = useState(null);
|
||||||
const [partyStreams, setPartyStreams] = useState({});
|
const [partyStreams, setPartyStreams] = useState({});
|
||||||
function handlePeerConnected({ peer }) {
|
function handlePeerConnected(peer) {
|
||||||
peer.send({ id: "nickname", data: { [socket.id]: nickname } });
|
peer.connection.send({ id: "nickname", data: { [socket.id]: nickname } });
|
||||||
if (stream) {
|
if (stream) {
|
||||||
peer.addStream(stream);
|
peer.connection.addStream(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handlePeerData({ data, peer }) {
|
function handlePeerData({ data, peer }) {
|
||||||
if (data.id === "sync") {
|
if (data.id === "sync") {
|
||||||
if (mapSource) {
|
if (mapSource) {
|
||||||
peer.send({ id: "map", data: mapDataRef.current });
|
peer.connection.send({ id: "map", data: mapDataRef.current });
|
||||||
}
|
}
|
||||||
if (mapTokens) {
|
if (mapTokens) {
|
||||||
peer.send({ id: "tokenEdit", data: mapTokens });
|
peer.connection.send({ id: "tokenEdit", data: mapTokens });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (data.id === "map") {
|
if (data.id === "map") {
|
||||||
@ -116,29 +116,33 @@ function Game() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handlePeerDisconnected(disconnectedId) {
|
function handlePeerDisconnected(peer) {
|
||||||
setPartyNicknames((prevNicknames) => omit(prevNicknames, [disconnectedId]));
|
setPartyNicknames((prevNicknames) => omit(prevNicknames, [peer.id]));
|
||||||
}
|
}
|
||||||
|
|
||||||
const [peerError, setPeerError] = useState(null);
|
const [peerError, setPeerError] = useState(null);
|
||||||
function handlePeerError(error) {
|
function handlePeerError({ error, peer }) {
|
||||||
setPeerError(error.message || "Unknown Error Occurred.");
|
setPeerError(
|
||||||
|
`${
|
||||||
|
peer.id === socket.id ? "" : `(${partyNicknames[peer.id] || "Unknown"})`
|
||||||
|
} ${error.message || "Unknown Error Occurred."}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handlePeerTrackAdded({ id, stream: remoteStream }) {
|
function handlePeerTrackAdded({ peer, stream: remoteStream }) {
|
||||||
setPartyStreams((prevStreams) => ({
|
setPartyStreams((prevStreams) => ({
|
||||||
...prevStreams,
|
...prevStreams,
|
||||||
[id]: remoteStream,
|
[peer.id]: remoteStream,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
function handlePeerTrackRemoved({ id, stream: remoteStream }) {
|
function handlePeerTrackRemoved({ peer, stream: remoteStream }) {
|
||||||
if (isStreamStopped(remoteStream)) {
|
if (isStreamStopped(remoteStream)) {
|
||||||
setPartyStreams((prevStreams) => omit(prevStreams, [id]));
|
setPartyStreams((prevStreams) => omit(prevStreams, [peer.id]));
|
||||||
} else {
|
} else {
|
||||||
setPartyStreams((prevStreams) => ({
|
setPartyStreams((prevStreams) => ({
|
||||||
...prevStreams,
|
...prevStreams,
|
||||||
[id]: remoteStream,
|
[peer.id]: remoteStream,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -150,7 +154,7 @@ function Game() {
|
|||||||
// Only add the audio track of the stream to the remote peer
|
// Only add the audio track of the stream to the remote peer
|
||||||
if (track.kind === "audio") {
|
if (track.kind === "audio") {
|
||||||
for (let peer of Object.values(peers)) {
|
for (let peer of Object.values(peers)) {
|
||||||
peer.addTrack(track, localStream);
|
peer.connection.addTrack(track, localStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,7 +169,7 @@ function Game() {
|
|||||||
// Only sending audio so only remove the audio track
|
// Only sending audio so only remove the audio track
|
||||||
if (track.kind === "audio") {
|
if (track.kind === "audio") {
|
||||||
for (let peer of Object.values(peers)) {
|
for (let peer of Object.values(peers)) {
|
||||||
peer.removeTrack(track, localStream);
|
peer.connection.removeTrack(track, localStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user