Skip to content

Commit 76980b9

Browse files
committed
add multi connect support
1 parent 80d8884 commit 76980b9

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

src/hooks/usePeer/index.ts

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,3 +158,97 @@ export function useHostPeerSession<T>(
158158

159159
return [partnerState, myState, setMyState, isConnected, myID];
160160
}
161+
162+
// Hook usage:
163+
164+
// const [peerStates, myState, setMyState, myID, numConnections, error] = useHostMultiPeerSession<StateInterface>()
165+
interface PeerDataPair<T> {
166+
id: string;
167+
data: T;
168+
}
169+
170+
export function useHostMultiPeerSession<T>( initialState: T): [PeerDataPair<T>[], T, (state: T) => void, string, number, string?] {
171+
const [peerStates, setPeerStates] = useState<PeerDataPair<T>[]>([]);
172+
const [myState, setMyState] = useState<T>(initialState);
173+
const [myID, setMyID] = useState('');
174+
const [error, setError] = useState<string>();
175+
const [peer, setPeer] = useState<any>();
176+
const conns = peer?.connections.length;
177+
const [_numConnections, setNumConnections] = useState(conns); // used to force a re-render when the number of connections changes, actual value is not used as peer object has a connections property
178+
179+
180+
181+
useEffect(
182+
() => {
183+
const shouldGetNewID = myID === '';
184+
const IDToUse = shouldGetNewID ? generateID() : myID;
185+
console.log(`IDToUse: ${IDToUse}`);
186+
187+
if (peer && !shouldGetNewID) {
188+
return;
189+
} else {
190+
if (peer && shouldGetNewID) {
191+
peer.destroy();
192+
}
193+
194+
import('peerjs').then(({ default: Peer }) => {
195+
const peer = new Peer(IDToUse);
196+
setPeer(peer);
197+
peer.on('open', (id) => {
198+
setMyID(id);
199+
peer.on('connection', (conn) => {
200+
{
201+
/*@ts-ignore*/ }
202+
conn.on('data', (data: T) => {
203+
setPeerStates((prev) => {
204+
const newState = [...prev];
205+
const index = newState.findIndex((p) => p.id === conn.peer);
206+
if (index === -1) {
207+
newState.push({ id: conn.peer, data });
208+
} else {
209+
newState[index] = { id: conn.peer, data };
210+
}
211+
return newState;
212+
});
213+
});
214+
215+
setNumConnections((prev: number) => prev + 1);
216+
});
217+
});
218+
peer.on('error', (err) => {
219+
console.error(err);
220+
setError(err.message);
221+
});
222+
223+
peer.on('close', () => {
224+
setNumConnections(0);
225+
});
226+
227+
peer.on('disconnected', () => {
228+
setNumConnections(0);
229+
});
230+
});
231+
}
232+
},
233+
// eslint-disable-next-line react-hooks/exhaustive-deps
234+
[myID, conns]
235+
);
236+
237+
const connections = Object.values(peer?.connections || {});
238+
239+
useEffect(() => {
240+
if (myState && connections) {
241+
connections.forEach((conn: any) => {
242+
if (conn && conn[0]) {
243+
conn[0].send(myState);
244+
} else {
245+
setNumConnections((prev: number) => prev - 1);
246+
}
247+
});
248+
}
249+
}
250+
// eslint-disable-next-line react-hooks/exhaustive-deps
251+
, [myState, connections, connections.length]);
252+
253+
return [peerStates, myState, setMyState, myID, conns, error];
254+
}

0 commit comments

Comments
 (0)