Classroom güncellemesi

This commit is contained in:
Sedat Öztürk 2025-08-31 11:06:03 +03:00
parent b3415a4222
commit 6cc2c0f5db
4 changed files with 31 additions and 17 deletions

View file

@ -221,7 +221,8 @@ public class ClassroomHub : Hub
}
await Clients.Group(sessionId.ToString())
.SendAsync("ParticipantLeft", userId.Value);
.SendAsync("ParticipantLeft", new { UserId = userId.Value, SessionId = sessionId });
_logger.LogInformation("User {UserId} left class {SessionId}", userId, sessionId);
}
@ -393,12 +394,12 @@ public class ClassroomHub : Hub
await Groups.RemoveFromGroupAsync(participant.ConnectionId, sessionId.ToString());
await DeactivateParticipantAsync(participant);
await Clients.Group(sessionId.ToString()).SendAsync("ParticipantLeft", participantId);
await Clients.Group(sessionId.ToString())
.SendAsync("ParticipantLeft", new { UserId = participantId, SessionId = sessionId });
}
// 3. Diğerlerine duyur
_logger.LogInformation("👢 Participant {ParticipantId} kicked from session {SessionId}", participantId, sessionId);
await Clients.Group(sessionId.ToString()).SendAsync("ParticipantLeft", participantId);
}
catch (Exception ex)
{
@ -528,7 +529,8 @@ public class ClassroomHub : Hub
// 🔑 Frontende bildir
await Clients.Group(participant.SessionId.ToString())
.SendAsync("ParticipantLeft", userId.Value);
.SendAsync("ParticipantLeft", new { UserId = userId.Value, SessionId = participant.SessionId });
}
}
catch (TaskCanceledException)

View file

@ -56,6 +56,7 @@ export interface ClassroomAttendanceDto {
export interface ClassroomParticipantDto {
id: string
name: string
sessionId: string
isTeacher: boolean
isObserver?: boolean
isAudioMuted?: boolean

View file

@ -21,7 +21,7 @@ export class SignalRService {
isTeacher: boolean,
isActive: boolean,
) => void
private onParticipantLeft?: (userId: string) => void
private onParticipantLeft?: (payload: { userId: string; sessionId: string }) => void
private onChatMessage?: (message: ClassroomChatDto) => void
private onParticipantMuted?: (userId: string, isMuted: boolean) => void
private onHandRaiseReceived?: (studentId: string) => void
@ -60,8 +60,8 @@ export class SignalRService {
},
)
this.connection.on('ParticipantLeft', (userId: string) => {
this.onParticipantLeft?.(userId)
this.connection.on('ParticipantLeft', (payload: { userId: string; sessionId: string }) => {
this.onParticipantLeft?.(payload)
})
this.connection.on('ChatMessage', (message: any) => {
@ -101,16 +101,23 @@ export class SignalRService {
this.isConnected = true
})
this.connection.onclose(async () => {
this.connection.onclose(async (err) => {
this.isConnected = false
// Eğer kick sebebiyle kapandıysa tekrar LeaveClass deneme
if (this.isKicked) {
this.currentSessionId = undefined
return
}
try {
if (this.currentSessionId) {
await this.connection.invoke('LeaveClass', this.currentSessionId)
}
} catch (err) {
console.warn('LeaveClass could not be sent, maybe server already closed', err)
console.warn('LeaveClass could not be sent, connection was already closed')
} finally {
this.currentSessionId = undefined // ✅ garanti sıfırlama
this.currentSessionId = undefined
}
})
@ -182,7 +189,7 @@ export class SignalRService {
console.log('Error starting SignalR connection simulating leave class for user', auth.user.id)
// Simulate successful leave in demo mode
setTimeout(() => {
this.onParticipantLeft?.(auth.user.id)
this.onParticipantLeft?.({ userId: auth.user.id, sessionId })
}, 100)
return
}
@ -364,7 +371,7 @@ export class SignalRService {
async kickParticipant(sessionId: string, participantId: string): Promise<void> {
if (!this.isConnected) {
setTimeout(() => {
this.onParticipantLeft?.(participantId)
this.onParticipantLeft?.({ userId: participantId, sessionId })
}, 100)
return
}
@ -435,7 +442,7 @@ export class SignalRService {
this.onParticipantJoined = callback
}
setParticipantLeaveHandler(callback: (userId: string) => void) {
setParticipantLeaveHandler(callback: (payload: { userId: string; sessionId: string }) => void) {
this.onParticipantLeft = callback
}

View file

@ -290,6 +290,7 @@ const RoomDetail: React.FC = () => {
updated.push({
id: userId,
name,
sessionId: classSession.id,
isTeacher,
isAudioMuted: classSettings.defaultMicrophoneState === 'muted',
isVideoMuted: classSettings.defaultCameraState === 'off',
@ -334,6 +335,7 @@ const RoomDetail: React.FC = () => {
updated.push({
id: participant.userId,
name: participant.userName,
sessionId: classSession.id,
isTeacher: participant.isTeacher,
isAudioMuted: classSettings.defaultMicrophoneState === 'muted',
isVideoMuted: classSettings.defaultCameraState === 'off',
@ -373,14 +375,16 @@ const RoomDetail: React.FC = () => {
},
)
signalRServiceRef.current.setParticipantLeaveHandler((userId) => {
console.log(`Participant left: ${userId}`)
signalRServiceRef.current.setParticipantLeaveHandler(({ userId, sessionId }) => {
console.log(`Participant left: ${userId} from session ${sessionId}`)
// peer connectionı kapat
webRTCServiceRef.current?.closePeerConnection(userId)
// katılımcıyı stateden sil
setParticipants((prev) => prev.filter((p) => p.id !== userId))
// katılımcıyı stateden tamamen sil
setParticipants((prev) =>
prev.filter((p) => !(p.id === userId && p.sessionId === sessionId)),
)
})
signalRServiceRef.current.setAttendanceUpdatedHandler((record) => {