Files
chain33-im/comet/bucket.go
2022-03-17 15:55:27 +08:00

160 lines
3.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package comet
import (
"sync"
"sync/atomic"
"gitlab.33.cn/chat/im/api/comet/grpc"
"gitlab.33.cn/chat/im/comet/conf"
)
// Bucket is a channel holder.
type Bucket struct {
c *conf.Bucket
cLock sync.RWMutex // protect the channels for chs
chs map[string]*Channel // map sub key to a channel
//group
groups map[string]*Group
routines []chan *grpc.BroadcastGroupReq
routinesNum uint64
}
// NewBucket new a bucket struct. store the key with im channel.
func NewBucket(c *conf.Bucket) (b *Bucket) {
b = new(Bucket)
b.chs = make(map[string]*Channel, c.Channel)
b.c = c
b.groups = make(map[string]*Group, c.Groups)
b.routines = make([]chan *grpc.BroadcastGroupReq, c.RoutineAmount)
for i := uint64(0); i < c.RoutineAmount; i++ {
c := make(chan *grpc.BroadcastGroupReq, c.RoutineSize)
b.routines[i] = c
go b.groupProc(c)
}
return
}
// ChannelCount channel count in the bucket
func (b *Bucket) ChannelCount() int {
return len(b.chs)
}
// Put put a channel according with sub key.
func (b *Bucket) Put(ch *Channel) (err error) {
b.cLock.Lock()
// close old channel
if dch := b.chs[ch.Key]; dch != nil {
dch.Close()
}
b.chs[ch.Key] = ch
b.cLock.Unlock()
return
}
// Del delete the channel by sub key.
func (b *Bucket) Del(dch *Channel) {
var (
ok bool
ch *Channel
)
b.cLock.Lock()
if ch, ok = b.chs[dch.Key]; ok {
if ch == dch {
//修改内容:获取channel下所有添加的群并逐个在群聊中删除该channel修改人dld;修改时间2021年5月8日16:36:00 c4f618a9-1c37-3459-3861-a24f26bb2d85
for id := range ch.Groups() {
if g := b.groups[id]; g != nil {
g.Del(ch)
}
}
//结束c4f618a9-1c37-3459-3861-a24f26bb2d85
delete(b.chs, ch.Key)
}
}
b.cLock.Unlock()
}
// Channel get a channel by sub key.
func (b *Bucket) Channel(key string) (ch *Channel) {
b.cLock.RLock()
ch = b.chs[key]
b.cLock.RUnlock()
return
}
// Broadcast push msgs to all channels in the bucket.
func (b *Bucket) Broadcast(p *grpc.Proto, op int32) {
var ch *Channel
b.cLock.RLock()
for _, ch = range b.chs {
_, _ = ch.Push(p)
}
b.cLock.RUnlock()
}
// group
// GroupCount room count in the bucket
func (b *Bucket) GroupCount() int {
return len(b.groups)
}
// GroupsCount get all group id where online number > 0.
func (b *Bucket) GroupsCount() (res map[string]int32) {
var (
groupID string
group *Group
)
b.cLock.RLock()
res = make(map[string]int32)
for groupID, group = range b.groups {
if group.Online > 0 {
res[groupID] = group.Online
}
}
b.cLock.RUnlock()
return
}
// Put put a group according with sub key.
func (b *Bucket) PutGroup(gid string) (group *Group, err error) {
var ok bool
b.cLock.Lock()
if group, ok = b.groups[gid]; !ok {
group = NewGroup(gid)
b.groups[gid] = group
}
b.cLock.Unlock()
return
}
// Group get a group by group id.
func (b *Bucket) Group(gid string) (group *Group) {
b.cLock.RLock()
group = b.groups[gid]
b.cLock.RUnlock()
return
}
// DelGroup delete a room by group id.
func (b *Bucket) DelGroup(group *Group) {
b.cLock.Lock()
delete(b.groups, group.ID)
b.cLock.Unlock()
group.Close()
}
// BroadcastGroup broadcast a message to specified group
func (b *Bucket) BroadcastGroup(arg *grpc.BroadcastGroupReq) {
num := atomic.AddUint64(&b.routinesNum, 1) % b.c.RoutineAmount
b.routines[num] <- arg
}
// group proc
func (b *Bucket) groupProc(c chan *grpc.BroadcastGroupReq) {
for {
arg := <-c
if group := b.Group(arg.GroupID); group != nil {
group.Push(arg.Proto)
}
}
}