Initial commit
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
package redis
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"sync"
|
||||
"videoweb/pub/common/log"
|
||||
"videoweb/pub/common/srvdef"
|
||||
|
||||
"github.com/go-redis/redis"
|
||||
)
|
||||
|
||||
type SubscribeCallback func(channel RCType, message string)
|
||||
|
||||
var (
|
||||
redisCli *redis.Client
|
||||
opts Options
|
||||
|
||||
//订阅参数
|
||||
pubsub *redis.PubSub
|
||||
subCBMap map[RCType]SubscribeCallback
|
||||
cbMapLock sync.RWMutex
|
||||
)
|
||||
|
||||
func Client() *redis.Client {
|
||||
return redisCli
|
||||
}
|
||||
|
||||
func Disconnect() {
|
||||
if redisCli != nil {
|
||||
if pubsub != nil {
|
||||
pubsub.Close()
|
||||
}
|
||||
redisCli.Close()
|
||||
redisCli = nil
|
||||
}
|
||||
}
|
||||
|
||||
func Init(opts Options) error {
|
||||
c := redis.NewClient(
|
||||
&redis.Options{
|
||||
Addr: opts.Addr,
|
||||
Password: opts.Psw,
|
||||
DB: opts.Db,
|
||||
},
|
||||
)
|
||||
|
||||
if err := c.Ping().Err(); err != nil {
|
||||
log.Error(fmt.Sprintf("[error] ping redis err %+v\n", err))
|
||||
return err
|
||||
}
|
||||
redisCli = c
|
||||
|
||||
pubsub = nil
|
||||
if opts.Subscribe {
|
||||
subCBMap = make(map[RCType]SubscribeCallback)
|
||||
pubsub = redisCli.Subscribe()
|
||||
//接受发布消息
|
||||
go ReceiveMessage()
|
||||
}
|
||||
|
||||
log.Info("redis:Init Ok!")
|
||||
return nil
|
||||
}
|
||||
|
||||
// OnMessage 订阅消息回调
|
||||
func OnMessage(channel RCType, message string) {
|
||||
cbMapLock.RLock()
|
||||
defer cbMapLock.RUnlock()
|
||||
flag := false
|
||||
for k, v := range subCBMap {
|
||||
reg := regexp.MustCompile(string(k))
|
||||
//log.Info("test", log.Any("k", k), log.Any("channelchannel", channel))
|
||||
if b := reg.MatchString(string(channel)); b {
|
||||
v(channel, message)
|
||||
flag = true
|
||||
}
|
||||
}
|
||||
if !flag {
|
||||
log.Warn("(redis:OnMessage) callback doesn't exist!", log.Any("channel", channel))
|
||||
}
|
||||
}
|
||||
|
||||
// ReceiveMessage 接受发布消息
|
||||
func ReceiveMessage() {
|
||||
for {
|
||||
msg, err := pubsub.Receive()
|
||||
if err != nil {
|
||||
fmt.Println("test1", err)
|
||||
return
|
||||
}
|
||||
|
||||
switch msg := msg.(type) {
|
||||
case *redis.Subscription:
|
||||
// Ignore.
|
||||
log.Info("(redis:ReceiveMessage) subscribe success!", log.Any("channel", msg.Channel))
|
||||
case *redis.Pong:
|
||||
// Ignore.
|
||||
fmt.Println("Pong")
|
||||
case *redis.Message:
|
||||
channel := msg.Channel
|
||||
message := msg.Payload
|
||||
OnMessage(RCType(channel), message)
|
||||
default:
|
||||
log.Error("(redis:ReceiveMessage) msg!", log.Any("msg", msg))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Subscribe 订阅一个消息
|
||||
func Subscribe(channel RCType, cb SubscribeCallback) *srvdef.SrvErr {
|
||||
if pubsub == nil {
|
||||
log.Warn("(redis:Subscribe) subscribe is not enabled!")
|
||||
return srvdef.New(srvdef.ErrRdsOperError, "", "")
|
||||
}
|
||||
err := pubsub.Subscribe(string(channel))
|
||||
if err != nil {
|
||||
log.Warn("(redis:Subscribe) Subscribe failed!", log.Any("err", err))
|
||||
return srvdef.New(srvdef.ErrRdsOperError, "", "")
|
||||
}
|
||||
cbMapLock.Lock()
|
||||
defer cbMapLock.Unlock()
|
||||
subCBMap[channel] = cb
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnSubscribe 取消订阅一个消息
|
||||
func UnSubscribe(channel RCType, cb SubscribeCallback) *srvdef.SrvErr {
|
||||
if pubsub == nil {
|
||||
log.Warn("(redis:UnSubscribe) subscribe is not enabled!")
|
||||
return srvdef.New(srvdef.ErrRdsOperError, "", "")
|
||||
}
|
||||
err := pubsub.Unsubscribe(string(channel))
|
||||
if err != nil {
|
||||
log.Warn("(redis:UnSubscribe) UnSubscribe failed!", log.Any("err", err))
|
||||
return srvdef.New(srvdef.ErrRdsOperError, "", "")
|
||||
}
|
||||
cbMapLock.Lock()
|
||||
defer cbMapLock.Unlock()
|
||||
delete(subCBMap, channel)
|
||||
return nil
|
||||
}
|
||||
|
||||
// PSubscribe 模式匹配消息
|
||||
func PSubscribe(channel RCType, cb SubscribeCallback) *srvdef.SrvErr {
|
||||
if pubsub == nil {
|
||||
log.Warn("(redis:PSubscribe) subscribe is not enabled!")
|
||||
return srvdef.New(srvdef.ErrRdsOperError, "", "")
|
||||
}
|
||||
err := pubsub.PSubscribe(string(channel))
|
||||
if err != nil {
|
||||
log.Warn("(redis:PSubscribe) PSubscribe failed!", log.Any("err", err))
|
||||
return srvdef.New(srvdef.ErrRdsOperError, "", "")
|
||||
}
|
||||
cbMapLock.Lock()
|
||||
defer cbMapLock.Unlock()
|
||||
subCBMap[channel] = cb
|
||||
return nil
|
||||
}
|
||||
|
||||
// PUnsubscribe 模式取消匹配消息
|
||||
func PUnsubscribe(channel RCType, cb SubscribeCallback) *srvdef.SrvErr {
|
||||
if pubsub == nil {
|
||||
log.Warn("(redis:PUnsubscribe) subscribe is not enabled!")
|
||||
return srvdef.New(srvdef.ErrRdsOperError, "", "")
|
||||
}
|
||||
err := pubsub.PUnsubscribe(string(channel))
|
||||
if err != nil {
|
||||
log.Warn("(redis:PUnsubscribe) PUnsubscribe failed!", log.Any("err", err))
|
||||
return srvdef.New(srvdef.ErrRdsOperError, "", "")
|
||||
}
|
||||
cbMapLock.Lock()
|
||||
defer cbMapLock.Unlock()
|
||||
delete(subCBMap, channel)
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user