classroom düzeltmeler
This commit is contained in:
parent
b67080646c
commit
8acbd2e257
8 changed files with 62 additions and 75 deletions
|
|
@ -372,6 +372,7 @@ public class ClassroomHub : Hub
|
|||
{
|
||||
try
|
||||
{
|
||||
// 1. Attendance kapat
|
||||
var attendances = await _attendanceRepository.GetListAsync(
|
||||
x => x.SessionId == sessionId && x.StudentId == participantId && x.LeaveTime == null
|
||||
);
|
||||
|
|
@ -381,42 +382,60 @@ public class ClassroomHub : Hub
|
|||
foreach (var attendance in attendances)
|
||||
{
|
||||
await CloseAttendanceAsync(attendance);
|
||||
await Clients.Group(sessionId.ToString()).SendAsync("AttendanceUpdated", attendance);
|
||||
await Clients.Group(sessionId.ToString())
|
||||
.SendAsync("AttendanceUpdated", attendance);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Participant bul
|
||||
var participant = await _participantRepository.FirstOrDefaultAsync(
|
||||
x => x.SessionId == sessionId && x.UserId == participantId
|
||||
);
|
||||
|
||||
if (participant != null && !string.IsNullOrEmpty(participant.ConnectionId))
|
||||
if (participant == null)
|
||||
{
|
||||
await Clients.Client(participant.ConnectionId)
|
||||
.SendAsync("ForceDisconnect", "You have been removed from the class.");
|
||||
|
||||
await Groups.RemoveFromGroupAsync(participant.ConnectionId, sessionId.ToString());
|
||||
|
||||
// ❌ pasif + ✅ kicked işaretle
|
||||
participant.IsActive = false;
|
||||
participant.IsKicked = true;
|
||||
participant.ConnectionId = null;
|
||||
await _participantRepository.UpdateAsync(participant, autoSave: true);
|
||||
|
||||
await Clients.Group(sessionId.ToString())
|
||||
.SendAsync("ParticipantLeft", new { UserId = participantId, SessionId = sessionId });
|
||||
_logger.LogWarning("KickParticipant: Session {SessionId} için participant {ParticipantId} bulunamadı",
|
||||
sessionId, participantId);
|
||||
return;
|
||||
}
|
||||
|
||||
// ConnectionId'yi kaydet (DB'ye null yazmadan önce)
|
||||
var connectionId = participant.ConnectionId;
|
||||
|
||||
// 3. Diğerlerine duyur
|
||||
_logger.LogInformation("👢 Participant {ParticipantId} kicked from session {SessionId}", participantId, sessionId);
|
||||
// 3. DB'de kick flag setle
|
||||
participant.IsActive = false;
|
||||
participant.IsKicked = true;
|
||||
participant.ConnectionId = null;
|
||||
|
||||
await _participantRepository.UpdateAsync(participant, autoSave: true);
|
||||
|
||||
// 4. Hedef kullanıcıya bildir
|
||||
if (!string.IsNullOrEmpty(connectionId))
|
||||
{
|
||||
await Clients.Client(connectionId)
|
||||
.SendAsync("ForceDisconnect", "You have been removed from the class.");
|
||||
|
||||
await Groups.RemoveFromGroupAsync(connectionId, sessionId.ToString());
|
||||
}
|
||||
|
||||
// 5. Diğer katılımcılara bildir
|
||||
await Clients.Group(sessionId.ToString())
|
||||
.SendAsync("ParticipantLeft", new { UserId = participantId, SessionId = sessionId });
|
||||
|
||||
// 6. Log
|
||||
_logger.LogInformation("👢 Participant {ParticipantId} kicked from session {SessionId}",
|
||||
participantId, sessionId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "❌ KickParticipant hata verdi");
|
||||
_logger.LogError(ex, "❌ KickParticipant hata verdi (Session={SessionId}, Participant={ParticipantId})",
|
||||
sessionId, participantId);
|
||||
|
||||
await Clients.Caller.SendAsync("Error", "Kick işlemi başarısız oldu.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[HubMethodName("ApproveHandRaise")]
|
||||
public async Task ApproveHandRaiseAsync(Guid sessionId, Guid studentId)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -281,8 +281,7 @@ const RoomDetail: React.FC = () => {
|
|||
signalRServiceRef.current.setParticipantJoinHandler(
|
||||
async (userId: string, name: string, isTeacher: boolean, isActive: boolean) => {
|
||||
if (userId === user.id) return
|
||||
if (!isActive) return // ❌ pasif kullanıcıyı ekleme
|
||||
if (isTeacher) setTeacherDisconnected(false)
|
||||
if (!isActive) return
|
||||
|
||||
console.log(`Participant joined: ${name}, isTeacher: ${isTeacher}`)
|
||||
|
||||
|
|
@ -296,31 +295,19 @@ const RoomDetail: React.FC = () => {
|
|||
isTeacher,
|
||||
isAudioMuted: classSettings.defaultMicrophoneState === 'muted',
|
||||
isVideoMuted: classSettings.defaultCameraState === 'off',
|
||||
isActive: isActive, // ✅ state’de tut
|
||||
isActive: true,
|
||||
})
|
||||
}
|
||||
|
||||
// ✅ güncel listedeki öğretmen kontrolü
|
||||
const teacherExists = updated.some((p) => p.isTeacher && p.isActive)
|
||||
|
||||
if (teacherExists) {
|
||||
;(async () => {
|
||||
if (!webRTCServiceRef.current?.getPeerConnection(userId)) {
|
||||
await webRTCServiceRef.current?.createPeerConnection(userId)
|
||||
}
|
||||
|
||||
// ✅ öğretmen ise her zaman offer başlatır
|
||||
if (isActive) {
|
||||
if (user.role === 'teacher') {
|
||||
const offer = await webRTCServiceRef.current!.createOffer(userId)
|
||||
await signalRServiceRef.current?.sendOffer(classSession.id, userId, offer)
|
||||
}
|
||||
}
|
||||
})()
|
||||
}
|
||||
|
||||
return updated
|
||||
})
|
||||
|
||||
// 🔑 Mesh: Herkes herkese offer gönderir
|
||||
if (!webRTCServiceRef.current?.getPeerConnection(userId)) {
|
||||
await webRTCServiceRef.current?.createPeerConnection(userId)
|
||||
}
|
||||
|
||||
const offer = await webRTCServiceRef.current!.createOffer(userId)
|
||||
await signalRServiceRef.current?.sendOffer(classSession.id, userId, offer)
|
||||
},
|
||||
)
|
||||
|
||||
|
|
@ -329,12 +316,12 @@ const RoomDetail: React.FC = () => {
|
|||
async (
|
||||
existing: { userId: string; userName: string; isTeacher: boolean; isActive: boolean }[],
|
||||
) => {
|
||||
setParticipants((prev) => {
|
||||
let updated = [...prev]
|
||||
for (const participant of existing) {
|
||||
if (!participant.isActive) continue
|
||||
if (participant.userId === user.id) continue
|
||||
|
||||
for (const participant of existing) {
|
||||
if (!participant.isActive) continue // ❌ pasif kullanıcıyı alma
|
||||
if (participant.userId === user.id) continue
|
||||
setParticipants((prev) => {
|
||||
const updated = [...prev]
|
||||
if (!updated.find((p) => p.id === participant.userId)) {
|
||||
updated.push({
|
||||
id: participant.userId,
|
||||
|
|
@ -343,39 +330,20 @@ const RoomDetail: React.FC = () => {
|
|||
isTeacher: participant.isTeacher,
|
||||
isAudioMuted: classSettings.defaultMicrophoneState === 'muted',
|
||||
isVideoMuted: classSettings.defaultCameraState === 'off',
|
||||
isActive: participant.isActive, // ✅ state’de tut
|
||||
isActive: true,
|
||||
})
|
||||
}
|
||||
return updated
|
||||
})
|
||||
|
||||
if (!webRTCServiceRef.current?.getPeerConnection(participant.userId)) {
|
||||
await webRTCServiceRef.current?.createPeerConnection(participant.userId)
|
||||
}
|
||||
|
||||
// ✅ güncel listede öğretmen var mı?
|
||||
const teacherExists = updated.some((p) => p.isTeacher && p.isActive)
|
||||
|
||||
if (teacherExists) {
|
||||
;(async () => {
|
||||
for (const participant of existing) {
|
||||
if (!participant.isActive) continue
|
||||
if (participant.userId === user.id) continue
|
||||
|
||||
if (!webRTCServiceRef.current?.getPeerConnection(participant.userId)) {
|
||||
await webRTCServiceRef.current?.createPeerConnection(participant.userId)
|
||||
}
|
||||
|
||||
// ✅ sadece öğretmen offer başlatır
|
||||
if (user.role === 'teacher') {
|
||||
const offer = await webRTCServiceRef.current!.createOffer(participant.userId)
|
||||
await signalRServiceRef.current?.sendOffer(
|
||||
classSession.id,
|
||||
participant.userId,
|
||||
offer,
|
||||
)
|
||||
}
|
||||
}
|
||||
})()
|
||||
}
|
||||
|
||||
return updated
|
||||
})
|
||||
// 🔑 Mesh: yeni gelen user da karşıya offer yollar
|
||||
const offer = await webRTCServiceRef.current!.createOffer(participant.userId)
|
||||
await signalRServiceRef.current?.sendOffer(classSession.id, participant.userId, offer)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue