gnet
gnet copied to clipboard
[Question]: How to shut down the started tcp server and turn off port listening?
Actions I've taken before I'm here
- [X] I've thoroughly read the documentations about this problem but still have no answer.
- [X] I've searched the Github Issues/Discussions but didn't find any similar problems that have been solved.
- [X] I've searched the internet for this problem but didn't find anything helpful.
Questions with details
调用eng.Stop(context.Background())后端口依然被占用。请问如何解决?一下是我的完整版代码
Code snippets (optional)
package initializer
import (
"context"
"encoding/json"
"fmt"
"github.com/panjf2000/gnet/v2"
"github.com/sirupsen/logrus"
"time"
)
type Discoverer struct {
ts tcpServer
us udpServer
onInitReq func(params initParams) error
}
func NewDiscoverer() *Discoverer {
d := &Discoverer{}
d.ts = tcpServer{
onMessage: d.onTcpMessage,
}
d.us = udpServer{
onMessage: d.onUdpMessage,
}
return d
}
func (d *Discoverer) comeToLight() (err error) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
var (
tcpDone = make(chan bool, 1)
tcpFlag bool
udpFlag bool
udpDone = make(chan bool, 1)
errCh = make(chan error)
)
go func() {
time.AfterFunc(time.Second*2, func() {
tcpDone <- true
})
if e := gnet.Run(d.ts, "tcp://:12345",
gnet.WithMulticore(true),
gnet.WithReuseAddr(true),
gnet.WithReusePort(true)); e != nil {
errCh <- fmt.Errorf("discover tcp server run failed with error: %s", e)
return
}
}()
go func() {
time.AfterFunc(time.Second*2, func() {
udpDone <- true
})
if e := gnet.Run(d.us, "udp://:54321", gnet.WithMulticore(true),
gnet.WithReuseAddr(true),
gnet.WithReusePort(true)); e != nil {
errCh <- fmt.Errorf("discover udp server run failed with error: %s", e)
}
}()
for {
if tcpFlag && udpFlag {
return
}
select {
case tcpFlag = <-tcpDone:
case udpFlag = <-udpDone:
case err = <-errCh:
return
case <-ctx.Done():
return fmt.Errorf("server run operation timed out: %s", ctx.Err())
}
}
}
func (d *Discoverer) hide() {
logrus.Info("Gateway Discoverer to hide.")
d.ts.close()
d.us.close()
}
type initParams struct {
DeviceName string `json:"deviceName"`
Host string `json:"host"`
Port int `json:"port"`
ProvisionType string `json:"provisionType"`
ProvisionDeviceKey string `json:"provisionDeviceKey"`
ProvisionDeviceSecret string `json:"provisionDeviceSecret"`
}
func (d *Discoverer) onTcpMessage(payload []byte, c gnet.Conn) {
params := initParams{}
m := map[string]any{
"code": 1,
}
if err := json.Unmarshal(payload, ¶ms); err != nil {
logrus.Warnf("Gateway discoverer unmarshal json for tcp init request failed with err: %s", err)
m["code"] = 0
m["msg"] = fmt.Sprintf("Gateway discoverer unmarshal json for init request failed with err: %s", err)
goto response
}
if d.onInitReq != nil {
if err := d.onInitReq(params); err != nil {
m["code"] = 0
m["msg"] = fmt.Sprintf("Gateway discoverer handler init failed with err: %s", err)
}
}
response:
bytes, _ := json.Marshal(&m)
_, _ = c.Write(bytes)
}
func (d *Discoverer) onUdpMessage(_ []byte, c gnet.Conn) {
bs, err := json.Marshal(map[string]any{
"model": "yunqi.gateway.tb1",
})
if err != nil {
logrus.Warnf("Gateway discoverer marshal json for udp reponse failed with err: %s", err)
}
_, err = c.Write(bs)
if err != nil {
logrus.Warnf("Gateway discoverer write udp reponse failed with err: %s", err)
}
}
type tcpServer struct {
*gnet.BuiltinEventEngine
eng gnet.Engine
onMessage func([]byte, gnet.Conn)
}
type udpServer struct {
*gnet.BuiltinEventEngine
eng gnet.Engine
onMessage func([]byte, gnet.Conn)
}
func (t tcpServer) OnBoot(eng gnet.Engine) (action gnet.Action) {
t.eng = eng
logrus.Infof("Discoverer tcp server is boot")
return
}
func (t tcpServer) OnShutdown(gnet.Engine) {
logrus.Infof("Discoverer tcp server is shutdown")
return
}
func (t tcpServer) OnOpen(c gnet.Conn) (out []byte, action gnet.Action) {
logrus.Infof("Discoverer tcp client is open for: %s", c.RemoteAddr())
return
}
func (t tcpServer) OnClose(c gnet.Conn, err error) (action gnet.Action) {
logrus.Infof("Discoverer tcp client is close for: %s, error: %s", c.Close(), err)
return
}
func (t tcpServer) OnTraffic(c gnet.Conn) (action gnet.Action) {
bytes, _ := c.Next(-1)
pkg := make([]byte, len(bytes))
copy(pkg, bytes)
if t.onMessage != nil {
t.onMessage(bytes, c)
}
logrus.Debugf("Discoverer tcp server message: %s, length: %d", c.RemoteAddr().String(), len(pkg))
return
}
func (t tcpServer) close() {
_ = t.eng.Stop(context.Background())
}
func (u udpServer) OnBoot(eng gnet.Engine) (action gnet.Action) {
u.eng = eng
logrus.Infof("Discoverer udp server is boot")
return
}
func (u udpServer) OnShutdown(gnet.Engine) {
logrus.Infof("Discoverer udp server is shutdown")
return
}
func (u udpServer) OnOpen(c gnet.Conn) (out []byte, action gnet.Action) {
logrus.Infof("Discoverer udp client is open for: %s", c.RemoteAddr())
return
}
func (u udpServer) OnClose(c gnet.Conn, err error) (action gnet.Action) {
logrus.Infof("Discoverer udp client is close for: %s, error: %s", c.Close(), err)
return
}
func (u udpServer) OnTraffic(c gnet.Conn) (action gnet.Action) {
bytes, _ := c.Next(-1)
pkg := make([]byte, len(bytes))
copy(pkg, bytes)
logrus.Debugf("Discoverer udp server message: %s, length: %d", c.RemoteAddr().String(), len(pkg))
if u.onMessage != nil {
u.onMessage(bytes, c)
}
return
}
func (u udpServer) close() {
_ = u.eng.Stop(context.Background())
}