代码拉取完成,页面将自动刷新
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)
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。