notify/client.go
2019-12-05 16:45:30 +08:00

173 lines
3.8 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 notify
import (
"net"
"strings"
"time"
"b612.me/starainrt"
)
// StarNotifyC 为Client端
type StarNotifyC struct {
connc net.Conn
clientSign map[string]chan string
// FuncLists 当不使用channel时使用此记录调用函数
FuncLists map[string]func(CMsg)
clientStopSign chan int
defaultFunc func(CMsg)
// Stop 停止信号
Stop chan int
// UseChannel 是否使用channel作为信息传递
UseChannel bool
notifychan chan int
isUDP bool
// Queue 是用来处理收发信息的简单消息队列
Queue *starainrt.StarQueue
// Online 当前链接是否处于活跃状态
Online bool
}
// CMsg 指明当前客户端被通知的关键字
type CMsg struct {
Key string
Value string
}
func (star *StarNotifyC) starinitc() {
star.Queue = starainrt.NewQueue()
star.FuncLists = make(map[string]func(CMsg))
star.UseChannel = true
star.clientStopSign, star.notifychan, star.Stop = make(chan int, 1), make(chan int, 3), make(chan int, 5)
star.clientSign = make(map[string]chan string)
star.Online = false
}
// Notify 用于获取一个通知
func (star *StarNotifyC) Notify(key string) chan string {
if _, ok := star.clientSign[key]; !ok {
ch := make(chan string, 20)
star.clientSign[key] = ch
}
return star.clientSign[key]
}
func (star *StarNotifyC) store(key, value string) {
if _, ok := star.clientSign[key]; !ok {
ch := make(chan string, 20)
ch <- value
star.clientSign[key] = ch
return
}
star.clientSign[key] <- value
}
// NewNotifyC 用于新建一个Client端进程
func NewNotifyC(netype, value string) (*StarNotifyC, error) {
var err error
var star StarNotifyC
star.starinitc()
star.isUDP = false
if strings.Index(netype, "udp") >= 0 {
star.isUDP = true
}
star.connc, err = net.Dial(netype, value)
if err != nil {
return nil, err
}
go star.cnotify()
go func() {
for {
go func() {
<-star.clientStopSign
star.notifychan <- 2
star.connc.Close()
star.Stop <- 0
star.Online = false
return
}()
buf := make([]byte, 8192)
n, err := star.connc.Read(buf)
if err != nil {
star.connc.Close()
star.Stop <- 1
star.notifychan <- 3
//star, _ = NewNotifyC(netype, value)
star.Online = false
return
}
if n != 0 {
star.Queue.ParseMessage(buf[0:n], star.connc)
}
}
}()
star.Online = true
return &star, nil
}
// Send 用于向Server端发送数据
func (star *StarNotifyC) Send(name string) error {
_, err := star.connc.Write(star.Queue.BuildMessage(name))
return err
}
// SendValue 用于向Server端发送key-value类型数据
func (star *StarNotifyC) SendValue(name, value string) error {
_, err := star.connc.Write(star.Queue.BuildMessage(name + "||" + value))
return err
}
func (star *StarNotifyC) cnotify() {
for {
select {
case <-star.notifychan:
return
default:
}
data, err := star.Queue.RestoreOne()
if err != nil {
time.Sleep(time.Millisecond * 20)
continue
}
if data.Msg == "b612ryzstop" {
star.clientStopSign <- 0
star.Online = false
return
}
strs := strings.SplitN(data.Msg, "||", 2)
if len(strs) < 2 {
continue
}
if star.UseChannel {
go star.store(strs[0], strs[1])
} else {
key, value := strs[0], strs[1]
if msg, ok := star.FuncLists[key]; ok {
go msg(CMsg{key, value})
} else {
if star.defaultFunc != nil {
go star.defaultFunc(CMsg{key, value})
}
}
}
}
}
// ClientStop 终止client端运行
func (star *StarNotifyC) ClientStop() {
if star.isUDP {
star.Send("b612ryzstop")
}
star.clientStopSign <- 1
}
// SetNotify 用于设置关键词的调用函数
func (star *StarNotifyC) SetNotify(name string, data func(CMsg)) {
star.FuncLists[name] = data
}
// SetDefaultNotify 用于设置默认关键词的调用函数
func (star *StarNotifyC) SetDefaultNotify(name string, data func(CMsg)) {
star.defaultFunc = data
}