This commit is contained in:
2022-03-17 15:55:27 +08:00
commit bd5a9fad97
92 changed files with 13861 additions and 0 deletions

159
comet/bucket.go Normal file
View File

@@ -0,0 +1,159 @@
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)
}
}
}