Classroom signalRService inject edildi.

This commit is contained in:
Sedat Öztürk 2025-08-31 23:52:21 +03:00
parent 879a54fcea
commit 60ced627b4
2 changed files with 51 additions and 2 deletions

View file

@ -1,5 +1,10 @@
export class WebRTCService { export class WebRTCService {
private peerConnections: Map<string, RTCPeerConnection> = new Map() private peerConnections: Map<string, RTCPeerConnection> = new Map()
private retryCounts: Map<string, number> = new Map() // 🔑 her kullanıcı için retry sayacı
private maxRetries = 3 // 🔑 maksimum yeniden deneme sayısı
private signalRService: any // 👈 dışarıdan set edilecek SignalR servisi
private sessionId: string = '' // oturum için de lazım olabilir
private localStream: MediaStream | null = null private localStream: MediaStream | null = null
private onRemoteStream?: (userId: string, stream: MediaStream) => void private onRemoteStream?: (userId: string, stream: MediaStream) => void
private onIceCandidate?: (userId: string, candidate: RTCIceCandidateInit) => void private onIceCandidate?: (userId: string, candidate: RTCIceCandidateInit) => void
@ -56,6 +61,7 @@ export class WebRTCService {
async createPeerConnection(userId: string): Promise<RTCPeerConnection> { async createPeerConnection(userId: string): Promise<RTCPeerConnection> {
const peerConnection = new RTCPeerConnection(this.rtcConfiguration) const peerConnection = new RTCPeerConnection(this.rtcConfiguration)
this.peerConnections.set(userId, peerConnection) this.peerConnections.set(userId, peerConnection)
this.retryCounts.set(userId, 0) // bağlantı başında sıfırla
// Eğer local stream varsa track'leri ekle // Eğer local stream varsa track'leri ekle
if (this.localStream) { if (this.localStream) {
@ -75,12 +81,29 @@ export class WebRTCService {
} }
} }
peerConnection.onconnectionstatechange = () => { peerConnection.onconnectionstatechange = async () => {
const state = peerConnection.connectionState const state = peerConnection.connectionState
console.log(`Bağlantı durumu [${userId}]: ${state}`) console.log(`Bağlantı durumu [${userId}]: ${state}`)
if (['failed', 'closed'].includes(state)) {
if (state === 'closed') {
this.closePeerConnection(userId) this.closePeerConnection(userId)
} }
if (state === 'failed') {
let retries = this.retryCounts.get(userId) ?? 0
if (retries < this.maxRetries) {
console.warn(
`⚠️ Bağlantı failed oldu, ICE restart deneniyor [${userId}] (Deneme ${retries + 1})`,
)
this.retryCounts.set(userId, retries + 1)
await this.restartIce(peerConnection, userId)
} else {
console.error(
`❌ Bağlantı ${this.maxRetries} denemede başarısız [${userId}], peer kapatılıyor.`,
)
this.closePeerConnection(userId)
}
}
} }
// En sona ekle // En sona ekle
@ -99,6 +122,11 @@ export class WebRTCService {
return peerConnection return peerConnection
} }
setSignalRService(signalRService: any, sessionId: string) {
this.signalRService = signalRService
this.sessionId = sessionId
}
setIceCandidateHandler(callback: (userId: string, candidate: RTCIceCandidateInit) => void) { setIceCandidateHandler(callback: (userId: string, candidate: RTCIceCandidateInit) => void) {
this.onIceCandidate = callback this.onIceCandidate = callback
} }
@ -232,12 +260,31 @@ export class WebRTCService {
return this.localStream return this.localStream
} }
private async restartIce(peerConnection: RTCPeerConnection, userId: string) {
try {
const offer = await peerConnection.createOffer({ iceRestart: true })
await peerConnection.setLocalDescription(offer)
console.log(`ICE restart başlatıldı [${userId}]`)
// 🔑 SignalR üzerinden karşı tarafa gönder
if (this.signalRService) {
await this.signalRService.sendOffer(this.sessionId, userId, offer)
console.log(`ICE restart offer karşıya gönderildi [${userId}]`)
} else {
console.warn('⚠️ SignalR servisi bağlı değil, offer gönderilemedi')
}
} catch (err) {
console.error(`ICE restart başarısız [${userId}]:`, err)
}
}
closePeerConnection(userId: string): void { closePeerConnection(userId: string): void {
const peerConnection = this.peerConnections.get(userId) const peerConnection = this.peerConnections.get(userId)
if (peerConnection) { if (peerConnection) {
peerConnection.getSenders().forEach((sender) => sender.track?.stop()) peerConnection.getSenders().forEach((sender) => sender.track?.stop())
peerConnection.close() peerConnection.close()
this.peerConnections.delete(userId) this.peerConnections.delete(userId)
this.retryCounts.delete(userId) // sayaç temizle
} }
} }

View file

@ -240,6 +240,8 @@ const RoomDetail: React.FC = () => {
// WebRTC başlat // WebRTC başlat
webRTCServiceRef.current = new WebRTCService() webRTCServiceRef.current = new WebRTCService()
webRTCServiceRef.current.setSignalRService(signalRServiceRef.current, classSession.id)
const stream = await webRTCServiceRef.current.initializeLocalStream(micEnabled, camEnabled) const stream = await webRTCServiceRef.current.initializeLocalStream(micEnabled, camEnabled)
if (stream) { if (stream) {
setLocalStream(stream) setLocalStream(stream)