103 lines
1.9 KiB
Go
103 lines
1.9 KiB
Go
package comet
|
|
|
|
import (
|
|
"errors"
|
|
"sync"
|
|
"sync/atomic"
|
|
|
|
"github.com/Terry-Mao/goim/pkg/bufio"
|
|
"github.com/golang/protobuf/proto"
|
|
"gitlab.33.cn/chat/im/api/comet/grpc"
|
|
)
|
|
|
|
// Channel used by message pusher send msg to write goroutine.
|
|
type Channel struct {
|
|
CliProto Ring
|
|
signal chan *grpc.Proto
|
|
Writer bufio.Writer
|
|
Reader bufio.Reader
|
|
|
|
Seq int32
|
|
Key string
|
|
IP string
|
|
Port string
|
|
|
|
nodes map[string]*Node
|
|
mutex sync.RWMutex
|
|
}
|
|
|
|
// NewChannel new a channel.
|
|
func NewChannel(cli, svr int) *Channel {
|
|
c := new(Channel)
|
|
c.CliProto.Init(cli)
|
|
c.signal = make(chan *grpc.Proto, svr)
|
|
c.nodes = make(map[string]*Node)
|
|
return c
|
|
}
|
|
|
|
// Push server push message.
|
|
func (c *Channel) seqInc() int32 {
|
|
return atomic.AddInt32(&c.Seq, 1)
|
|
}
|
|
|
|
// Push server push message.
|
|
func (c *Channel) push(p *grpc.Proto) (err error) {
|
|
select {
|
|
case c.signal <- p:
|
|
default:
|
|
}
|
|
return
|
|
}
|
|
|
|
// Push server push message.
|
|
func (c *Channel) Push(p *grpc.Proto) (seq int32, err error) {
|
|
if p, ok := proto.Clone(p).(*grpc.Proto); ok {
|
|
if p.Op == int32(grpc.Op_ReceiveMsg) {
|
|
p.Seq = c.seqInc()
|
|
}
|
|
seq = p.Seq
|
|
return seq, c.push(p)
|
|
} else {
|
|
return 0, errors.New("protocol type gRPC proto failed")
|
|
}
|
|
}
|
|
|
|
// Ready check the channel ready or close?
|
|
func (c *Channel) Ready() *grpc.Proto {
|
|
return <-c.signal
|
|
}
|
|
|
|
// Signal send signal to the channel, protocol ready.
|
|
func (c *Channel) Signal() {
|
|
c.signal <- grpc.ProtoReady
|
|
}
|
|
|
|
// Close close the channel.
|
|
func (c *Channel) Close() {
|
|
c.signal <- grpc.ProtoFinish
|
|
}
|
|
|
|
// Close close the channel.
|
|
func (c Channel) Groups() map[string]*Node {
|
|
return c.nodes
|
|
}
|
|
|
|
//
|
|
func (c *Channel) DelNode(id string) {
|
|
c.mutex.Lock()
|
|
delete(c.nodes, id)
|
|
c.mutex.Unlock()
|
|
}
|
|
|
|
func (c *Channel) SetNode(id string, node *Node) {
|
|
c.mutex.Lock()
|
|
c.nodes[id] = node
|
|
c.mutex.Unlock()
|
|
}
|
|
|
|
func (c *Channel) GetNode(id string) *Node {
|
|
c.mutex.Lock()
|
|
defer c.mutex.Unlock()
|
|
return c.nodes[id]
|
|
}
|