Hatalar için düzenleme

This commit is contained in:
Sedat Öztürk 2025-08-31 23:26:49 +03:00
parent bbd2f338b6
commit 879a54fcea
5 changed files with 58 additions and 36 deletions

View file

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.Json.Serialization;
using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.Domain.Entities.Auditing;
namespace Kurs.Platform.Entities; namespace Kurs.Platform.Entities;
@ -20,6 +21,7 @@ public class Classroom : FullAuditedEntity<Guid>
public int ParticipantCount { get; set; } public int ParticipantCount { get; set; }
public string SettingsJson { get; set; } public string SettingsJson { get; set; }
[JsonIgnore]
public virtual ICollection<ClassroomParticipant> Participants { get; set; } public virtual ICollection<ClassroomParticipant> Participants { get; set; }
public virtual ICollection<ClassroomAttandance> AttendanceRecords { get; set; } public virtual ICollection<ClassroomAttandance> AttendanceRecords { get; set; }
public virtual ICollection<ClassroomChat> ChatMessages { get; set; } public virtual ICollection<ClassroomChat> ChatMessages { get; set; }

View file

@ -1,4 +1,5 @@
using System; using System;
using System.Text.Json.Serialization;
using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.Domain.Entities.Auditing;
namespace Kurs.Platform.Entities; namespace Kurs.Platform.Entities;
@ -12,7 +13,7 @@ public class ClassroomAttandance : FullAuditedEntity<Guid>
public DateTime? LeaveTime { get; set; } public DateTime? LeaveTime { get; set; }
public int TotalDurationMinutes { get; set; } public int TotalDurationMinutes { get; set; }
// Navigation properties [JsonIgnore]
public virtual Classroom Session { get; set; } public virtual Classroom Session { get; set; }
protected ClassroomAttandance() protected ClassroomAttandance()

View file

@ -1,4 +1,5 @@
using System; using System;
using System.Text.Json.Serialization;
using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.Domain.Entities.Auditing;
namespace Kurs.Platform.Entities; namespace Kurs.Platform.Entities;
@ -15,7 +16,7 @@ public class ClassroomChat : FullAuditedEntity<Guid>
public bool IsTeacher { get; set; } public bool IsTeacher { get; set; }
public string MessageType { get; set; } public string MessageType { get; set; }
// Navigation properties [JsonIgnore]
public virtual Classroom Session { get; set; } public virtual Classroom Session { get; set; }
protected ClassroomChat() protected ClassroomChat()

View file

@ -1,4 +1,5 @@
using System; using System;
using System.Text.Json.Serialization;
using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.Domain.Entities.Auditing;
namespace Kurs.Platform.Entities; namespace Kurs.Platform.Entities;
@ -17,7 +18,7 @@ public class ClassroomParticipant : FullAuditedEntity<Guid>
public DateTime JoinTime { get; set; } public DateTime JoinTime { get; set; }
public string ConnectionId { get; set; } public string ConnectionId { get; set; }
// Navigation properties [JsonIgnore]
public virtual Classroom Session { get; set; } public virtual Classroom Session { get; set; }
protected ClassroomParticipant() protected ClassroomParticipant()

View file

@ -9,6 +9,7 @@ using Volo.Abp.Guids;
using Volo.Abp.Users; using Volo.Abp.Users;
using System.Linq; using System.Linq;
using System.Text.Json; using System.Text.Json;
using Volo.Abp.Uow;
namespace Kurs.Platform.Classrooms; namespace Kurs.Platform.Classrooms;
@ -22,6 +23,7 @@ public class ClassroomHub : Hub
private readonly ILogger<ClassroomHub> _logger; private readonly ILogger<ClassroomHub> _logger;
private readonly IGuidGenerator _guidGenerator; private readonly IGuidGenerator _guidGenerator;
private readonly ICurrentUser _currentUser; private readonly ICurrentUser _currentUser;
private readonly UnitOfWorkManager _unitOfWorkManager;
public ClassroomHub( public ClassroomHub(
IRepository<Classroom, Guid> classSessionRepository, IRepository<Classroom, Guid> classSessionRepository,
@ -30,7 +32,8 @@ public class ClassroomHub : Hub
IRepository<ClassroomAttandance, Guid> attendanceRepository, IRepository<ClassroomAttandance, Guid> attendanceRepository,
ILogger<ClassroomHub> logger, ILogger<ClassroomHub> logger,
IGuidGenerator guidGenerator, IGuidGenerator guidGenerator,
ICurrentUser currentUser) ICurrentUser currentUser,
UnitOfWorkManager unitOfWorkManager)
{ {
_classSessionRepository = classSessionRepository; _classSessionRepository = classSessionRepository;
_participantRepository = participantRepository; _participantRepository = participantRepository;
@ -39,6 +42,7 @@ public class ClassroomHub : Hub
_logger = logger; _logger = logger;
_guidGenerator = guidGenerator; _guidGenerator = guidGenerator;
_currentUser = currentUser; _currentUser = currentUser;
_unitOfWorkManager = unitOfWorkManager;
} }
#region Helper Methods #region Helper Methods
@ -392,7 +396,15 @@ public class ClassroomHub : Hub
// yalnızca diğer katılımcılar görebilsin // yalnızca diğer katılımcılar görebilsin
await Clients.Group(sessionId.ToString()) await Clients.Group(sessionId.ToString())
.SendAsync("AttendanceUpdated", attendance); .SendAsync("AttendanceUpdated", new {
attendance.Id,
attendance.SessionId,
attendance.StudentId,
attendance.StudentName,
attendance.JoinTime,
attendance.LeaveTime,
attendance.TotalDurationMinutes
});
} }
// 2. Participant bul // 2. Participant bul
@ -512,7 +524,7 @@ public class ClassroomHub : Hub
.SendAsync("ReceiveIceCandidate", _currentUser.Id?.ToString(), candidate); .SendAsync("ReceiveIceCandidate", _currentUser.Id?.ToString(), candidate);
} }
[UnitOfWork]
public override async Task OnDisconnectedAsync(Exception exception) public override async Task OnDisconnectedAsync(Exception exception)
{ {
try try
@ -524,9 +536,11 @@ public class ClassroomHub : Hub
return; return;
} }
_logger.LogInformation("🔴 OnDisconnectedAsync: User={UserId}, ConnId={ConnId}, Exception={Exception}", userId, Context.ConnectionId, exception?.Message); _logger.LogInformation("🔴 OnDisconnectedAsync: User={UserId}, ConnId={ConnId}, Exception={Exception}",
userId, Context.ConnectionId, exception?.Message);
// 🔑 Aynı anda birden fazla session olabilir (tab senaryosu) // 🔑 Yeni scope aç (her disconnect için ayrı UoW)
using var uow = _unitOfWorkManager.Begin(requiresNew: true, isTransactional: true);
var participants = await _participantRepository var participants = await _participantRepository
.GetListAsync(x => x.UserId == userId.Value && x.ConnectionId == Context.ConnectionId); .GetListAsync(x => x.UserId == userId.Value && x.ConnectionId == Context.ConnectionId);
@ -537,17 +551,16 @@ public class ClassroomHub : Hub
foreach (var participant in participants) foreach (var participant in participants)
{ {
_logger.LogInformation("OnDisconnectedAsync: User {UserId}, Session {SessionId} bağlantısı koptu.", userId, participant.SessionId); _logger.LogInformation("OnDisconnectedAsync: User {UserId}, Session {SessionId} bağlantısı koptu.",
userId, participant.SessionId);
// 🔑 Attendance kapat // 🔑 Attendance güncelle
var attendances = await _attendanceRepository.GetListAsync( var attendances = await _attendanceRepository.GetListAsync(
x => x.SessionId == participant.SessionId && x => x.SessionId == participant.SessionId &&
x.StudentId == userId.Value && x.StudentId == userId.Value &&
x.LeaveTime == null x.LeaveTime == null
); );
if (attendances != null)
{
foreach (var attendance in attendances) foreach (var attendance in attendances)
{ {
attendance.LeaveTime = DateTime.UtcNow; attendance.LeaveTime = DateTime.UtcNow;
@ -557,6 +570,7 @@ public class ClassroomHub : Hub
); );
await _attendanceRepository.UpdateAsync(attendance, autoSave: true); await _attendanceRepository.UpdateAsync(attendance, autoSave: true);
// DTO gönder (entity yerine)
await Clients.Group(participant.SessionId.ToString()) await Clients.Group(participant.SessionId.ToString())
.SendAsync("AttendanceUpdated", new .SendAsync("AttendanceUpdated", new
{ {
@ -569,9 +583,8 @@ public class ClassroomHub : Hub
attendance.TotalDurationMinutes attendance.TotalDurationMinutes
}); });
} }
}
// Eğer kullanıcı kick edilmemişse pasifleştir // Eğer kick edilmemişse → pasif et
if (!participant.IsKicked) if (!participant.IsKicked)
{ {
participant.IsActive = false; participant.IsActive = false;
@ -579,10 +592,16 @@ public class ClassroomHub : Hub
await _participantRepository.UpdateAsync(participant, autoSave: true); await _participantRepository.UpdateAsync(participant, autoSave: true);
await Clients.Group(participant.SessionId.ToString()) await Clients.Group(participant.SessionId.ToString())
.SendAsync("ParticipantLeft", new { UserId = userId.Value, SessionId = participant.SessionId }); .SendAsync("ParticipantLeft", new
{
UserId = userId.Value,
SessionId = participant.SessionId
});
}
} }
} // 🔑 Scope commit
await uow.CompleteAsync();
} }
catch (TaskCanceledException) catch (TaskCanceledException)
{ {
@ -597,8 +616,6 @@ public class ClassroomHub : Hub
} }
} }
public class SignalingMessageDto public class SignalingMessageDto
{ {
public string Type { get; set; } // offer, answer, ice-candidate public string Type { get; set; } // offer, answer, ice-candidate