package svc import ( "context" "lone-services/pkg/redis" pkgws "lone-services/pkg/ws" jsoniter "github.com/json-iterator/go" "github.com/zeromicro/go-zero/core/logx" ) type Subscriber struct { hub *Hub } func NewSubscriber(h *Hub) *Subscriber { return &Subscriber{hub: h} } func (s *Subscriber) Run(ctx context.Context) { if redis.Client == nil { logx.Error("ws pubsub: redis not initialized") return } sub := redis.Client.Subscribe(ctx, pkgws.RedisChannelQRPush) defer sub.Close() ch := sub.Channel() logx.Infof("ws pubsub: subscribed %s", pkgws.RedisChannelQRPush) for { select { case <-ctx.Done(): return case msg, ok := <-ch: if !ok { return } s.handle([]byte(msg.Payload)) } } } func (s *Subscriber) handle(raw []byte) { var evt pkgws.Event if err := jsoniter.Unmarshal(raw, &evt); err != nil { logx.Errorf("ws pubsub: unmarshal event: %v", err) return } if evt.SessionID == "" { return } resp := pkgws.Response{ Code: evt.Code, Message: evt.Message, Data: nil, } if len(evt.Data) > 0 && string(evt.Data) != "null" { var data any if err := jsoniter.Unmarshal(evt.Data, &data); err != nil { resp.Data = jsoniter.RawMessage(evt.Data) } else { resp.Data = data } } payload, err := jsoniter.Marshal(resp) if err != nil { logx.Errorf("ws pubsub: marshal response: %v", err) return } if !s.hub.Send(evt.SessionID, payload) { logx.Infof("ws pubsub: no local conn for session=%s", evt.SessionID) } }