init: 通用库抽离——httpx/logger/wsc/wscclient/jwtx(合并分叉副本); 顶层包布局; module path git.zeroonesoft.cn/golib/zogo

This commit is contained in:
w11
2026-09-19 19:04:01 +08:00
commit f0f5421262
17 changed files with 2336 additions and 0 deletions
+103
View File
@@ -0,0 +1,103 @@
package wsc
import (
"encoding/json"
"sync"
"github.com/sirupsen/logrus"
)
// Room 消息房间,用于业务隔离和群组广播。
type Room struct {
name string
members map[string]*Session
mu sync.RWMutex
onEmpty func(name string) // 房间空时回调
}
func newRoom(name string) *Room {
return &Room{
name: name,
members: make(map[string]*Session),
}
}
func (r *Room) Name() string { return r.name }
func (r *Room) Len() int {
r.mu.RLock()
defer r.mu.RUnlock()
return len(r.members)
}
func (r *Room) Join(ctx *Context) {
r.mu.Lock()
r.members[ctx.SessionID] = ctx.session
r.mu.Unlock()
}
func (r *Room) Leave(ctx *Context) {
r.mu.Lock()
delete(r.members, ctx.SessionID)
empty := len(r.members) == 0
r.mu.Unlock()
if empty && r.onEmpty != nil {
r.onEmpty(r.name)
}
}
// Broadcast 向房间成员广播 Message(json.Marshal 后发原始字节)。
func (r *Room) Broadcast(excludeSessionID string, msg Message) error {
m := map[string]any{"action": msg.Action}
if len(msg.Payload) > 0 {
// Payload 已是 json.RawMessage,直接复用
m["payload"] = msg.Payload
}
raw, err := json.Marshal(m)
if err != nil {
return err
}
return r.broadcastRaw(excludeSessionID, raw)
}
// BroadcastRaw 向房间成员广播已序列化的消息(性能优化)。
func (r *Room) BroadcastRaw(excludeSessionID string, data map[string]any) error {
raw, err := json.Marshal(data)
if err != nil {
return err
}
return r.broadcastRaw(excludeSessionID, raw)
}
// broadcastRaw 向房间成员发送原始字节(锁外已序列化)。
func (r *Room) broadcastRaw(excludeSessionID string, raw []byte) error {
r.mu.RLock()
defer r.mu.RUnlock()
for id, s := range r.members {
if id == excludeSessionID {
continue
}
if err := s.sendRaw(raw); err != nil {
logrus.Errorf("[wsc] broadcast send failed: session=%s, err=%v", id[:8], err)
}
}
return nil
}
// BroadcastAll 向房间所有成员广播。
func (r *Room) BroadcastAll(msg Message) error {
return r.Broadcast("", msg)
}
// SendTo 向房间内指定成员发送消息。
func (r *Room) SendTo(sessionID string, msg Message) error {
r.mu.RLock()
s, ok := r.members[sessionID]
r.mu.RUnlock()
if !ok {
return nil
}
return s.writeJSON(msg)
}