tam chat
This commit is contained in:
@@ -20,21 +20,56 @@ type SocketClient struct {
|
||||
Conn *websocket.Conn
|
||||
StudentID int64
|
||||
ClassID int64
|
||||
StaffID uint
|
||||
Role string // "student" | "teacher"
|
||||
Addr string
|
||||
}
|
||||
|
||||
type WsHub struct {
|
||||
mu sync.RWMutex
|
||||
students map[int64]*SocketClient
|
||||
teachers map[string]*SocketClient
|
||||
subscribers map[int64][]string // studentId -> list of teacher connection addresses
|
||||
mu sync.RWMutex
|
||||
students map[int64]*SocketClient
|
||||
teachers map[string]*SocketClient
|
||||
teachersByStaff map[uint][]string // staffId -> teacher connection addresses
|
||||
subscribers map[int64][]string // studentId -> list of teacher connection addresses
|
||||
}
|
||||
|
||||
var Hub = &WsHub{
|
||||
students: make(map[int64]*SocketClient),
|
||||
teachers: make(map[string]*SocketClient),
|
||||
subscribers: make(map[int64][]string),
|
||||
students: make(map[int64]*SocketClient),
|
||||
teachers: make(map[string]*SocketClient),
|
||||
teachersByStaff: make(map[uint][]string),
|
||||
subscribers: make(map[int64][]string),
|
||||
}
|
||||
|
||||
func (h *WsHub) IsStudentOnline(studentRkID int64) bool {
|
||||
h.mu.RLock()
|
||||
defer h.mu.RUnlock()
|
||||
_, ok := h.students[studentRkID]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (h *WsHub) PushChatToStudent(studentRkID int64, data map[string]any) {
|
||||
h.mu.RLock()
|
||||
client, ok := h.students[studentRkID]
|
||||
h.mu.RUnlock()
|
||||
if !ok || client == nil {
|
||||
return
|
||||
}
|
||||
_ = client.Conn.WriteJSON(SocketMsg{Event: "chat:message", Data: data})
|
||||
}
|
||||
|
||||
func (h *WsHub) PushChatToStaff(staffID uint, data map[string]any) {
|
||||
h.mu.RLock()
|
||||
addrs := append([]string(nil), h.teachersByStaff[staffID]...)
|
||||
h.mu.RUnlock()
|
||||
msg := SocketMsg{Event: "chat:message", Data: data}
|
||||
for _, addr := range addrs {
|
||||
h.mu.RLock()
|
||||
t, found := h.teachers[addr]
|
||||
h.mu.RUnlock()
|
||||
if found && t != nil {
|
||||
_ = t.Conn.WriteJSON(msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (h *WsHub) GetOnlineStudentIDs(classID int64) []int64 {
|
||||
@@ -63,7 +98,10 @@ func (h *WsHub) Register(c *SocketClient) {
|
||||
log.Printf("[WS] Student %d registered (Address: %s, Class: %d)", c.StudentID, c.Addr, c.ClassID)
|
||||
} else if c.Role == "teacher" {
|
||||
h.teachers[c.Addr] = c
|
||||
log.Printf("[WS] Teacher registered (Address: %s)", c.Addr)
|
||||
if c.StaffID > 0 {
|
||||
h.teachersByStaff[c.StaffID] = append(h.teachersByStaff[c.StaffID], c.Addr)
|
||||
}
|
||||
log.Printf("[WS] Teacher registered (Address: %s, Staff: %d)", c.Addr, c.StaffID)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +127,20 @@ func (h *WsHub) Unregister(c *SocketClient) {
|
||||
}
|
||||
} else if c.Role == "teacher" {
|
||||
delete(h.teachers, c.Addr)
|
||||
if c.StaffID > 0 {
|
||||
list := h.teachersByStaff[c.StaffID]
|
||||
next := list[:0]
|
||||
for _, addr := range list {
|
||||
if addr != c.Addr {
|
||||
next = append(next, addr)
|
||||
}
|
||||
}
|
||||
if len(next) == 0 {
|
||||
delete(h.teachersByStaff, c.StaffID)
|
||||
} else {
|
||||
h.teachersByStaff[c.StaffID] = next
|
||||
}
|
||||
}
|
||||
log.Printf("[WS] Teacher %s disconnected", c.Addr)
|
||||
|
||||
// Dọn dẹp subscriptions của giáo viên này
|
||||
@@ -206,9 +258,11 @@ func WebSocketHandler(db *gorm.DB) func(*websocket.Conn) {
|
||||
role := c.Query("role", "student")
|
||||
studentIDStr := c.Query("studentId", "0")
|
||||
classIDStr := c.Query("classId", "0")
|
||||
staffIDStr := c.Query("staffId", "0")
|
||||
|
||||
studentID, _ := strconv.ParseInt(studentIDStr, 10, 64)
|
||||
classID, _ := strconv.ParseInt(classIDStr, 10, 64)
|
||||
staffID64, _ := strconv.ParseUint(staffIDStr, 10, 64)
|
||||
|
||||
if role == "student" && db != nil {
|
||||
resolvedClassID := internalDb.FindActiveClassForStudent(db, studentID)
|
||||
@@ -221,6 +275,7 @@ func WebSocketHandler(db *gorm.DB) func(*websocket.Conn) {
|
||||
Conn: c,
|
||||
StudentID: studentID,
|
||||
ClassID: classID,
|
||||
StaffID: uint(staffID64),
|
||||
Role: role,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user