File size: 3,033 Bytes
811126d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
import { useEffect, useRef } from "react";
import { io, Socket } from "socket.io-client";
export function useGameSocket(gameId: string) {
const socketRef = useRef<Socket | null>(null);
const peerConnectionRef = useRef<RTCPeerConnection | null>(null);
useEffect(() => {
// Connexion au serveur de jeu
socketRef.current = io("http://localhost:5001", {
path: "/",
query: { gameId },
});
// Configuration WebRTC
const configuration = {
iceServers: [{ urls: "stun:stun.l.google.com:19302" }],
};
peerConnectionRef.current = new RTCPeerConnection(configuration);
// Gestion des événements Socket.IO
socketRef.current.on("offer", async (offer: RTCSessionDescriptionInit) => {
if (!peerConnectionRef.current) return;
await peerConnectionRef.current.setRemoteDescription(
new RTCSessionDescription(offer)
);
const answer = await peerConnectionRef.current.createAnswer();
await peerConnectionRef.current.setLocalDescription(answer);
socketRef.current?.emit("answer", answer);
});
socketRef.current.on(
"answer",
async (answer: RTCSessionDescriptionInit) => {
if (!peerConnectionRef.current) return;
await peerConnectionRef.current.setRemoteDescription(
new RTCSessionDescription(answer)
);
}
);
socketRef.current.on(
"candidate",
async (candidate: RTCIceCandidateInit) => {
if (!peerConnectionRef.current) return;
await peerConnectionRef.current.addIceCandidate(
new RTCIceCandidate(candidate)
);
}
);
// Gestion des candidats ICE
peerConnectionRef.current.onicecandidate = (event) => {
if (event.candidate) {
socketRef.current?.emit("candidate", event.candidate);
}
};
// Nettoyage à la déconnexion
return () => {
if (socketRef.current) {
socketRef.current.disconnect();
}
if (peerConnectionRef.current) {
peerConnectionRef.current.close();
}
};
}, [gameId]);
// Fonction pour démarrer un appel
const startCall = async (stream: MediaStream) => {
if (!peerConnectionRef.current || !socketRef.current) return;
// Ajout du flux audio local
stream.getTracks().forEach((track) => {
if (!peerConnectionRef.current) return;
peerConnectionRef.current.addTrack(track, stream);
});
// Création et envoi de l'offre
const offer = await peerConnectionRef.current.createOffer();
await peerConnectionRef.current.setLocalDescription(offer);
socketRef.current.emit("offer", offer);
};
// Fonction pour recevoir l'audio
const handleIncomingAudio = (onTrack: (stream: MediaStream) => void) => {
if (!peerConnectionRef.current) return;
peerConnectionRef.current.ontrack = (event) => {
onTrack(event.streams[0]);
};
};
return {
startCall,
handleIncomingAudio,
socket: socketRef.current,
peerConnection: peerConnectionRef.current,
};
}
|