go-common/app/interface/main/broadcast/server/room.go
2019-04-22 18:49:16 +08:00

91 lines
1.5 KiB
Go

package server
import (
"sync"
"go-common/app/service/main/broadcast/model"
)
// Room is a room.
type Room struct {
ID string
rLock sync.RWMutex
next *Channel
drop bool
Online int32 // dirty read is ok
AllOnline int32
}
// NewRoom new a room struct, store channel room info.
func NewRoom(id string) (r *Room) {
r = new(Room)
r.ID = id
r.drop = false
r.next = nil
r.AllOnline = roomOnline(id)
return
}
// Put put channel into the room.
func (r *Room) Put(ch *Channel) (err error) {
r.rLock.Lock()
if !r.drop {
if r.next != nil {
r.next.Prev = ch
}
ch.Next = r.next
ch.Prev = nil
r.next = ch // insert to header
r.Online++
} else {
err = ErrRoomDroped
}
r.rLock.Unlock()
return
}
// Del delete channel from the room.
func (r *Room) Del(ch *Channel) bool {
r.rLock.Lock()
if ch.Next != nil {
// if not footer
ch.Next.Prev = ch.Prev
}
if ch.Prev != nil {
// if not header
ch.Prev.Next = ch.Next
} else {
r.next = ch.Next
}
r.Online--
r.drop = (r.Online == 0)
r.rLock.Unlock()
return r.drop
}
// Push push msg to the room, if chan full discard it.
func (r *Room) Push(p *model.Proto) {
r.rLock.RLock()
for ch := r.next; ch != nil; ch = ch.Next {
ch.Push(p)
}
r.rLock.RUnlock()
}
// Close close the room.
func (r *Room) Close() {
r.rLock.RLock()
for ch := r.next; ch != nil; ch = ch.Next {
ch.Close()
}
r.rLock.RUnlock()
}
// OnlineNum the room all online.
func (r *Room) OnlineNum() int32 {
if r.AllOnline > 0 {
return r.AllOnline
}
return r.Online
}