4 Star 5 Fork 4

Plato/Service-Box-go

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
gnet_loop.go 3.60 KB
一键复制 编辑 原始数据 按行查看 历史
package net
import (
"context"
"errors"
"gitee.com/dennis-kk/service-box-go/util/slog"
"github.com/panjf2000/gnet"
"sync"
)
type listenMap map[string]bool
//gnetLoop gnet framework wrapper
type gnetLoop struct {
srvAddrs listenMap //server address cache !
connector IBoxConnector // client
sEH *serverEH //server event handle
cEH *clientEH //client event handle
netMQ NetEventQueue // send event to box
loopCh NetEventQueue // send event to loop
signal chan struct{} // notify single
wg sync.WaitGroup
}
func makeGnetLoop(v interface{}) IBoxNetLoop {
if mq, ok := v.(NetEventQueue); ok {
return &gnetLoop{
srvAddrs: make(listenMap),
connector: nil,
sEH: nil,
cEH: nil,
netMQ: mq,
loopCh: make(NetEventQueue, 16),
signal: make(chan struct{}),
wg: sync.WaitGroup{},
}
}
return nil
}
//Start create gnet instance
func (gl *gnetLoop) Start() error {
if gl == nil {
//TODO add error log and replace with common error
return nil
}
gl.sEH = makeServerEH(gl)
if gl.sEH == nil {
return nil
}
gl.cEH = makeClientEH(gl)
if gl.cEH == nil {
//TODO add error
return nil
}
gl.connector = BoxConnector(gl.cEH)
if err := gl.connector.Start(); err != nil {
return err
}
gl.wg.Add(1)
//start goroutine
go gl.loop()
// wait for goroutine start really
<-gl.signal
return nil
}
func (gl *gnetLoop) Stop() error {
if gl == nil {
return nil
}
ctx := context.Background()
for k := range gl.srvAddrs {
err := gnet.Stop(ctx, k)
if err != nil {
continue
}
}
gl.signal <- struct{}{}
close(gl.signal)
gl.wg.Wait()
close(gl.loopCh)
var err error
if err = gl.connector.Stop(); err != nil {
//TODO add some log
slog.Error("[ServiceBox] connector stop error !")
}
return err
}
func (gl *gnetLoop) Tick() {
}
func (gl *gnetLoop) loop() {
defer func() {
gl.wg.Done()
}()
//notify goroutine start
gl.signal <- struct{}{}
for {
select {
case event := <-gl.loopCh:
if event != nil {
gl.doNetReq(event)
}
// 等待关闭
case <-gl.signal:
return
}
}
}
func (gl *gnetLoop) Notify(data *EventData) {
if gl == nil || gl.netMQ == nil {
return
}
gl.netMQ <- data
}
func (gl *gnetLoop) SendToLoop(data *EventData) {
gl.loopCh <- data
}
func (gl *gnetLoop) doNetReq(event *EventData) {
switch event.NetType {
case EventReqConnect:
gl.doConnect(event)
}
}
func (gl *gnetLoop) ConnectTo(network, address string) (IBoxConn, error) {
if gl == nil || gl.connector == nil {
//TODO add log and print error !
return nil, errors.New("invalid connector")
}
return gl.connector.ConnectTo(network, address)
}
func (gl *gnetLoop) ListenAt(network, address string) error {
if gl == nil {
return nil
}
protoAddr := network + "://" + address
if _, ok := gl.srvAddrs[protoAddr]; ok {
//TODO add error log
return nil
}
gl.srvAddrs[protoAddr] = true
gl.wg.Add(1)
signal := make(chan struct{})
go func() {
defer gl.wg.Done()
//notify goroutine start
signal <- struct{}{}
err := gnet.Serve(gl.sEH, protoAddr, gnet.WithReuseAddr(true), gnet.WithTCPKeepAlive(0), gnet.WithTCPNoDelay(gnet.TCPNoDelay))
if err != nil {
slog.Error("Stop Server Listener %s error %v ", protoAddr, err)
return
}
}()
//wait for goroutine start
<-signal
return nil
}
func (gl *gnetLoop) doConnect(event *EventData) {
ctEvent := event.Data.(*ConnectToEvent)
nEvent := GetEventData()
nEvent.NetType = EventRespConnect
conn, err := gl.ConnectTo(ctEvent.Network, ctEvent.Addr)
nEvent.Data = &ConnectEvent{
Host: ctEvent.Addr,
Conn: conn,
}
nEvent.Err = err
gl.Notify(nEvent)
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/dennis-kk/service-box-go.git
git@gitee.com:dennis-kk/service-box-go.git
dennis-kk
service-box-go
Service-Box-go
v0.4.14

搜索帮助