This commit is contained in:
@@ -5197,6 +5197,14 @@ input:checked + .slider:before {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.grid-proctor-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.grid-proctor-layout {
|
||||
/* Columns configured inline */
|
||||
transition: all 0.3s ease;
|
||||
|
||||
@@ -23,8 +23,16 @@ type SocketClient struct {
|
||||
StaffID uint
|
||||
Role string // "student" | "teacher"
|
||||
Addr string
|
||||
writeMu sync.Mutex
|
||||
}
|
||||
|
||||
func (c *SocketClient) WriteJSON(v any) error {
|
||||
c.writeMu.Lock()
|
||||
defer c.writeMu.Unlock()
|
||||
return c.Conn.WriteJSON(v)
|
||||
}
|
||||
|
||||
|
||||
type WsHub struct {
|
||||
mu sync.RWMutex
|
||||
students map[int64]*SocketClient
|
||||
@@ -54,7 +62,7 @@ func (h *WsHub) PushExamToStudent(studentRkID int64, data map[string]any) {
|
||||
if !ok || client == nil {
|
||||
return
|
||||
}
|
||||
_ = client.Conn.WriteJSON(SocketMsg{Event: "exam:paper-sent", Data: data})
|
||||
_ = client.WriteJSON(SocketMsg{Event: "exam:paper-sent", Data: data})
|
||||
}
|
||||
|
||||
func (h *WsHub) PushChatToStudent(studentRkID int64, data map[string]any) {
|
||||
@@ -64,7 +72,7 @@ func (h *WsHub) PushChatToStudent(studentRkID int64, data map[string]any) {
|
||||
if !ok || client == nil {
|
||||
return
|
||||
}
|
||||
_ = client.Conn.WriteJSON(SocketMsg{Event: "chat:message", Data: data})
|
||||
_ = client.WriteJSON(SocketMsg{Event: "chat:message", Data: data})
|
||||
}
|
||||
|
||||
func (h *WsHub) PushChatToStaff(staffID uint, data map[string]any) {
|
||||
@@ -77,7 +85,7 @@ func (h *WsHub) PushChatToStaff(staffID uint, data map[string]any) {
|
||||
defer h.mu.RUnlock()
|
||||
for _, t := range h.teachers {
|
||||
if t != nil && t.Role == "teacher" {
|
||||
_ = t.Conn.WriteJSON(msg)
|
||||
_ = t.WriteJSON(msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -107,8 +115,8 @@ func (h *WsHub) Register(c *SocketClient) {
|
||||
h.students[c.StudentID] = c
|
||||
log.Printf("[WS] Student %d registered (Address: %s, Class: %d)", c.StudentID, c.Addr, c.ClassID)
|
||||
if subs, exists := h.subscribers[c.StudentID]; exists && len(subs) > 0 {
|
||||
_ = c.Conn.WriteJSON(SocketMsg{Event: "start_screenshot_stream"})
|
||||
_ = c.Conn.WriteJSON(SocketMsg{Event: "start_webcam_stream"})
|
||||
_ = c.WriteJSON(SocketMsg{Event: "start_screenshot_stream"})
|
||||
_ = c.WriteJSON(SocketMsg{Event: "start_webcam_stream"})
|
||||
log.Printf("[WS] Student %d has active subscribers. Sent start stream commands.", c.StudentID)
|
||||
}
|
||||
} else if c.Role == "teacher" {
|
||||
@@ -132,7 +140,7 @@ func (h *WsHub) Unregister(c *SocketClient) {
|
||||
if teachers, exists := h.subscribers[c.StudentID]; exists {
|
||||
for _, tAddr := range teachers {
|
||||
if t, found := h.teachers[tAddr]; found {
|
||||
_ = t.Conn.WriteJSON(SocketMsg{
|
||||
_ = t.WriteJSON(SocketMsg{
|
||||
Event: "teacher:stream-stopped",
|
||||
Data: map[string]any{"studentId": c.StudentID},
|
||||
})
|
||||
@@ -170,8 +178,8 @@ func (h *WsHub) Unregister(c *SocketClient) {
|
||||
delete(h.subscribers, sID)
|
||||
// Nếu không còn ai xem học sinh này, gửi lệnh tắt camera/screen cho client học sinh
|
||||
if student, exists := h.students[sID]; exists {
|
||||
_ = student.Conn.WriteJSON(SocketMsg{Event: "stop_screenshot_stream"})
|
||||
_ = student.Conn.WriteJSON(SocketMsg{Event: "stop_webcam_stream"})
|
||||
_ = student.WriteJSON(SocketMsg{Event: "stop_screenshot_stream"})
|
||||
_ = student.WriteJSON(SocketMsg{Event: "stop_webcam_stream"})
|
||||
}
|
||||
} else {
|
||||
h.subscribers[sID] = newList
|
||||
@@ -201,8 +209,8 @@ func (h *WsHub) Subscribe(teacherAddr string, studentID int64) {
|
||||
|
||||
// Phát lệnh cho máy học sinh bật stream (nếu học sinh đang online)
|
||||
if student, exists := h.students[studentID]; exists {
|
||||
_ = student.Conn.WriteJSON(SocketMsg{Event: "start_screenshot_stream"})
|
||||
_ = student.Conn.WriteJSON(SocketMsg{Event: "start_webcam_stream"})
|
||||
_ = student.WriteJSON(SocketMsg{Event: "start_screenshot_stream"})
|
||||
_ = student.WriteJSON(SocketMsg{Event: "start_webcam_stream"})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,8 +237,8 @@ func (h *WsHub) Unsubscribe(teacherAddr string, studentID int64) {
|
||||
|
||||
// Báo học sinh tắt camera & screen stream để tiết kiệm mạng và CPU
|
||||
if student, exists := h.students[studentID]; exists {
|
||||
_ = student.Conn.WriteJSON(SocketMsg{Event: "stop_screenshot_stream"})
|
||||
_ = student.Conn.WriteJSON(SocketMsg{Event: "stop_webcam_stream"})
|
||||
_ = student.WriteJSON(SocketMsg{Event: "stop_screenshot_stream"})
|
||||
_ = student.WriteJSON(SocketMsg{Event: "stop_webcam_stream"})
|
||||
}
|
||||
} else {
|
||||
h.subscribers[studentID] = newList
|
||||
@@ -262,7 +270,7 @@ func (h *WsHub) RelayFrame(studentID int64, event string, data map[string]any) {
|
||||
|
||||
for _, addr := range teachersList {
|
||||
if t, found := h.teachers[addr]; found {
|
||||
_ = t.Conn.WriteJSON(msg)
|
||||
_ = t.WriteJSON(msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user