多网络服务器启动器

This commit is contained in:
kercylan98 2023-04-22 14:23:07 +08:00
parent 26674fefa5
commit eee1caacbf
8 changed files with 168 additions and 45 deletions

11
go.mod
View File

@ -30,6 +30,7 @@ require (
github.com/goccy/go-json v0.10.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/pprof v0.0.0-20221203041831-ce31453925ec // indirect
github.com/jonboulle/clockwork v0.3.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
@ -63,11 +64,13 @@ require (
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
golang.org/x/crypto v0.5.0 // indirect
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect
golang.org/x/mod v0.7.0 // indirect
golang.org/x/net v0.7.0 // indirect
golang.org/x/mod v0.8.0 // indirect
golang.org/x/net v0.8.0 // indirect
golang.org/x/sys v0.7.0 // indirect
golang.org/x/text v0.7.0 // indirect
golang.org/x/tools v0.4.0 // indirect
golang.org/x/text v0.8.0 // indirect
golang.org/x/tools v0.6.0 // indirect
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect
google.golang.org/grpc v1.54.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect

14
go.sum
View File

@ -75,6 +75,8 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@ -235,6 +237,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA=
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -250,6 +254,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -284,6 +290,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@ -298,6 +306,7 @@ golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.4.0 h1:7mTAgkunk3fr4GAloyyCasadO6h9zSsQZbwvcaIciV4=
golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
@ -307,10 +316,14 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w=
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag=
google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -318,6 +331,7 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=

11
main.go
View File

@ -5,6 +5,13 @@ import (
)
func main() {
s := server.New(server.NetworkKcp)
s.Run(":9999")
ms := server.NewMultipleServer(
func() (addr string, srv *server.Server) {
return ":9999", server.New(server.NetworkTCP)
},
func() (addr string, srv *server.Server) {
return ":19999", server.New(server.NetworkGRPC)
},
)
ms.Run()
}

View File

@ -64,7 +64,12 @@ func (slf *event) OnConnectionReceivePacketEvent(conn *Conn, packet []byte) {
}
func (slf *event) check() {
if slf.network != NetworkHttp && len(slf.connectionReceivePacketEventHandles) == 0 {
log.Warn("Server", zap.String("ConnectionReceivePacketEvent", "Invalid server, no packets processed"))
switch slf.network {
case NetworkHttp, NetworkGRPC:
default:
if len(slf.connectionReceivePacketEventHandles) == 0 {
log.Warn("Server", zap.String("ConnectionReceivePacketEvent", "Invalid server, no packets processed"))
}
}
}

View File

@ -6,17 +6,17 @@ import (
"time"
)
type gServer struct {
type gNet struct {
*Server
connections *synchronization.Map[string, *Conn]
}
func (slf *gServer) OnInitComplete(server gnet.Server) (action gnet.Action) {
func (slf *gNet) OnInitComplete(server gnet.Server) (action gnet.Action) {
slf.connections = synchronization.NewMap[string, *Conn]()
return
}
func (slf *gServer) OnShutdown(server gnet.Server) {
func (slf *gNet) OnShutdown(server gnet.Server) {
for k := range slf.connections.Map() {
slf.connections.Delete(k)
}
@ -24,27 +24,27 @@ func (slf *gServer) OnShutdown(server gnet.Server) {
return
}
func (slf *gServer) OnOpened(c gnet.Conn) (out []byte, action gnet.Action) {
func (slf *gNet) OnOpened(c gnet.Conn) (out []byte, action gnet.Action) {
conn := newGNetConn(c)
slf.connections.Set(c.RemoteAddr().String(), conn)
slf.OnConnectionOpenedEvent(conn)
return
}
func (slf *gServer) OnClosed(c gnet.Conn, err error) (action gnet.Action) {
func (slf *gNet) OnClosed(c gnet.Conn, err error) (action gnet.Action) {
slf.OnConnectionClosedEvent(slf.connections.DeleteGet(c.RemoteAddr().String()))
return
}
func (slf *gServer) PreWrite(c gnet.Conn) {
func (slf *gNet) PreWrite(c gnet.Conn) {
return
}
func (slf *gServer) AfterWrite(c gnet.Conn, b []byte) {
func (slf *gNet) AfterWrite(c gnet.Conn, b []byte) {
return
}
func (slf *gServer) React(packet []byte, c gnet.Conn) (out []byte, action gnet.Action) {
func (slf *gNet) React(packet []byte, c gnet.Conn) (out []byte, action gnet.Action) {
if conn, exist := slf.connections.GetExist(c.RemoteAddr().String()); exist {
slf.Server.PushMessage(MessageTypePacket, conn, packet)
return nil, gnet.None
@ -53,6 +53,6 @@ func (slf *gServer) React(packet []byte, c gnet.Conn) (out []byte, action gnet.A
}
}
func (slf *gServer) Tick() (delay time.Duration, action gnet.Action) {
func (slf *gNet) Tick() (delay time.Duration, action gnet.Action) {
return
}

68
server/multiple.go Normal file
View File

@ -0,0 +1,68 @@
package server
import (
"go.uber.org/zap"
"minotaur/utils/log"
"os"
"os/signal"
"syscall"
"time"
)
func NewMultipleServer(serverHandle ...func() (addr string, srv *Server)) *MultipleServer {
ms := &MultipleServer{
servers: make([]*Server, len(serverHandle), len(serverHandle)),
addresses: make([]string, len(serverHandle), len(serverHandle)),
}
for i := 0; i < len(serverHandle); i++ {
ms.addresses[i], ms.servers[i] = serverHandle[i]()
}
return ms
}
type MultipleServer struct {
servers []*Server
addresses []string
}
func (slf *MultipleServer) Run() {
var exceptionChannel = make(chan error, 1)
defer close(exceptionChannel)
var running = make([]*Server, 0, len(slf.servers))
for i := 0; i < len(slf.servers); i++ {
go func(address string, server *Server) {
server.multiple = true
if err := server.Run(address); err != nil {
exceptionChannel <- err
} else {
running = append(running, server)
}
}(slf.addresses[i], slf.servers[i])
}
time.Sleep(time.Second)
log.Info("Server", zap.String("Minotaur Multiple Server", "===================================================================="))
for _, server := range slf.servers {
log.Info("Server", zap.String("Minotaur Multiple Server", "RunningInfo"),
zap.Any("network", server.network),
zap.String("listen", server.addr),
)
}
log.Info("Server", zap.String("Minotaur Multiple Server", "===================================================================="))
systemSignal := make(chan os.Signal, 1)
signal.Notify(systemSignal, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
select {
case err := <-exceptionChannel:
for _, server := range slf.servers {
server.Shutdown(err)
}
return
case <-systemSignal:
for _, server := range slf.servers {
server.Shutdown(nil)
}
return
}
}

View File

@ -13,4 +13,5 @@ const (
NetworkHttp Network = "http"
NetworkWebsocket Network = "websocket"
NetworkKcp Network = "kcp"
NetworkGRPC Network = "grpc"
)

View File

@ -7,7 +7,9 @@ import (
"github.com/panjf2000/gnet"
"github.com/xtaci/kcp-go/v5"
"go.uber.org/zap"
"google.golang.org/grpc"
"minotaur/utils/log"
"net"
"net/http"
"os"
"os/signal"
@ -32,11 +34,14 @@ func New(network Network) *Server {
// Server 网络服务器
type Server struct {
*event
network Network
addr string
httpServer *gin.Engine
gServer *gServer
messageChannel chan *message
network Network
addr string
httpServer *gin.Engine
grpcServer *grpc.Server
gServer *gNet
messageChannel chan *message
initMessageChannel bool
multiple bool
}
// Run 使用特定地址运行服务器
@ -58,10 +63,14 @@ func (slf *Server) Run(addr string) error {
slf.event.check()
slf.addr = addr
var protoAddr = fmt.Sprintf("%s://%s", slf.network, slf.addr)
var connectionInitHandle = func() {
var connectionInitHandle = func(callback func()) {
slf.initMessageChannel = true
slf.messageChannel = make(chan *message, 4096*1000)
if slf.network != NetworkHttp && slf.network != NetworkWebsocket {
slf.gServer = &gServer{Server: slf}
slf.gServer = &gNet{Server: slf}
}
if callback != nil {
go callback()
}
for message := range slf.messageChannel {
slf.dispatchMessage(message)
@ -69,20 +78,29 @@ func (slf *Server) Run(addr string) error {
}
switch slf.network {
case NetworkTCP, NetworkTCP4, NetworkTCP6, NetworkUdp, NetworkUdp4, NetworkUdp6, NetworkUnix:
go connectionInitHandle()
case NetworkGRPC:
listener, err := net.Listen(string(NetworkTCP), slf.addr)
if err != nil {
return err
}
slf.grpcServer = grpc.NewServer()
go func() {
if err := gnet.Serve(slf.gServer, protoAddr); err != nil {
if err := slf.grpcServer.Serve(listener); err != nil {
slf.PushMessage(MessageTypeError, err, MessageErrorActionShutdown)
}
}()
case NetworkTCP, NetworkTCP4, NetworkTCP6, NetworkUdp, NetworkUdp4, NetworkUdp6, NetworkUnix:
go connectionInitHandle(func() {
if err := gnet.Serve(slf.gServer, protoAddr); err != nil {
slf.PushMessage(MessageTypeError, err, MessageErrorActionShutdown)
}
})
case NetworkKcp:
listener, err := kcp.ListenWithOptions(slf.addr, nil, 0, 0)
if err != nil {
return err
}
go connectionInitHandle()
go func() {
go connectionInitHandle(func() {
for {
session, err := listener.AcceptKCP()
if err != nil {
@ -110,7 +128,7 @@ func (slf *Server) Run(addr string) error {
}
}(conn)
}
}()
})
case NetworkHttp:
go func() {
if err := slf.httpServer.Run(addr); err != nil {
@ -118,7 +136,7 @@ func (slf *Server) Run(addr string) error {
}
}()
case NetworkWebsocket:
go connectionInitHandle()
go connectionInitHandle(nil)
var pattern string
var index = strings.Index(addr, "/")
if index == -1 {
@ -178,29 +196,36 @@ func (slf *Server) Run(addr string) error {
return ErrCanNotSupportNetwork
}
log.Info("Server", zap.String("Minotaur Server", "===================================================================="))
log.Info("Server", zap.String("Minotaur Server", "RunningInfo"),
zap.Any("network", slf.network),
zap.String("listen", slf.addr),
)
log.Info("Server", zap.String("Minotaur Server", "===================================================================="))
if !slf.multiple {
log.Info("Server", zap.String("Minotaur Server", "===================================================================="))
log.Info("Server", zap.String("Minotaur Server", "RunningInfo"),
zap.Any("network", slf.network),
zap.String("listen", slf.addr),
)
log.Info("Server", zap.String("Minotaur Server", "===================================================================="))
systemSignal := make(chan os.Signal, 1)
signal.Notify(systemSignal, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
select {
case <-systemSignal:
slf.Shutdown(nil)
systemSignal := make(chan os.Signal, 1)
signal.Notify(systemSignal, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
select {
case <-systemSignal:
slf.Shutdown(nil)
}
}
return nil
}
// Shutdown 停止运行服务器
func (slf *Server) Shutdown(err error) {
close(slf.messageChannel)
if slf.initMessageChannel {
close(slf.messageChannel)
}
if err != nil {
log.Error("Server", zap.String("action", "shutdown"), zap.String("state", "exception"), zap.Error(err))
log.Error("Server", zap.Any("network", slf.network), zap.String("listen", slf.addr),
zap.String("action", "shutdown"), zap.String("state", "exception"), zap.Error(err))
} else {
log.Info("Server", zap.String("action", "shutdown"), zap.String("state", "normal"))
log.Info("Server", zap.Any("network", slf.network), zap.String("listen", slf.addr),
zap.String("action", "shutdown"), zap.String("state", "normal"))
}
}