91 lines
1.5 KiB
Go
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
|
|
}
|