mirror of
https://github.com/ehang-io/nps.git
synced 2026-03-19 16:12:59 +00:00
add new file
This commit is contained in:
32
core/server/server.go
Normal file
32
core/server/server.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package server
|
||||
|
||||
import "ehang.io/nps/core/handler"
|
||||
|
||||
type rule interface {
|
||||
handler.RuleRun
|
||||
GetHandler() handler.Handler
|
||||
}
|
||||
|
||||
type Server interface {
|
||||
Init() error
|
||||
Serve()
|
||||
GetServerAddr() string
|
||||
GetName() string
|
||||
GetZhName() string
|
||||
RegisterHandle(rl rule)
|
||||
}
|
||||
|
||||
type BaseServer struct {
|
||||
handlers map[string]handler.Handler
|
||||
}
|
||||
|
||||
func (bs *BaseServer) RegisterHandle(rl rule) {
|
||||
var h handler.Handler
|
||||
var ok bool
|
||||
if h, ok = bs.handlers[rl.GetHandler().GetName()]; !ok {
|
||||
h = rl.GetHandler()
|
||||
bs.handlers[h.GetName()] = h
|
||||
}
|
||||
h.AddRule(rl)
|
||||
return
|
||||
}
|
||||
97
core/server/tcp.go
Normal file
97
core/server/tcp.go
Normal file
@@ -0,0 +1,97 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"ehang.io/nps/core/handler"
|
||||
"ehang.io/nps/lib/enet"
|
||||
"ehang.io/nps/lib/logger"
|
||||
"ehang.io/nps/lib/pool"
|
||||
"github.com/panjf2000/ants/v2"
|
||||
"go.uber.org/zap"
|
||||
"io"
|
||||
"net"
|
||||
)
|
||||
|
||||
var bp = pool.NewBufferPool(1500)
|
||||
|
||||
type TcpServer struct {
|
||||
BaseServer
|
||||
ServerAddr string `json:"server_addr" required:"true" placeholder:"0.0.0.0:8080 or :8080" zh_name:"监听地址"`
|
||||
listener net.Listener
|
||||
gp *ants.PoolWithFunc
|
||||
}
|
||||
|
||||
func (cm *TcpServer) GetServerAddr() string {
|
||||
if cm.listener == nil {
|
||||
return cm.ServerAddr
|
||||
}
|
||||
return cm.listener.Addr().String()
|
||||
}
|
||||
|
||||
func (cm *TcpServer) Init() error {
|
||||
var err error
|
||||
cm.handlers = make(map[string]handler.Handler, 0)
|
||||
if err = cm.listen(); err != nil {
|
||||
return err
|
||||
}
|
||||
cm.gp, err = ants.NewPoolWithFunc(1000000, func(i interface{}) {
|
||||
rc := enet.NewReaderConn(i.(net.Conn))
|
||||
buf := bp.Get()
|
||||
defer bp.Put(buf)
|
||||
|
||||
if _, err := io.ReadAtLeast(rc, buf, 3); err != nil {
|
||||
logger.Warn("read handle type fom connection failed", zap.String("remote addr", rc.RemoteAddr().String()))
|
||||
_ = rc.Close()
|
||||
return
|
||||
}
|
||||
logger.Debug("read handle type", zap.Uint8("type 1", buf[0]), zap.Uint8("type 2", buf[1]),
|
||||
zap.Uint8("type 3", buf[2]), zap.String("remote addr", rc.RemoteAddr().String()))
|
||||
|
||||
for _, h := range cm.handlers {
|
||||
err = rc.Reset(0)
|
||||
if err != nil {
|
||||
logger.Warn("reset connection error", zap.Error(err), zap.String("remote addr", rc.RemoteAddr().String()))
|
||||
_ = rc.Close()
|
||||
return
|
||||
}
|
||||
ok, err := h.HandleConn(buf, rc)
|
||||
if err != nil {
|
||||
logger.Warn("handle connection error", zap.Error(err), zap.String("remote addr", rc.RemoteAddr().String()))
|
||||
return
|
||||
}
|
||||
if ok {
|
||||
logger.Debug("handle connection success", zap.String("remote addr", rc.RemoteAddr().String()))
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cm *TcpServer) GetName() string {
|
||||
return "tcp"
|
||||
}
|
||||
|
||||
func (cm *TcpServer) GetZhName() string {
|
||||
return "tcp服务"
|
||||
}
|
||||
|
||||
// create a listener accept user and npc
|
||||
func (cm *TcpServer) listen() error {
|
||||
var err error
|
||||
cm.listener, err = net.Listen("tcp", cm.ServerAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cm *TcpServer) Serve() {
|
||||
for {
|
||||
c, err := cm.listener.Accept()
|
||||
if err != nil {
|
||||
logger.Error("accept enet error", zap.Error(err))
|
||||
break
|
||||
}
|
||||
_ = cm.gp.Invoke(c)
|
||||
}
|
||||
}
|
||||
80
core/server/udp.go
Normal file
80
core/server/udp.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"ehang.io/nps/core/handler"
|
||||
"ehang.io/nps/lib/logger"
|
||||
"github.com/panjf2000/ants/v2"
|
||||
"go.uber.org/zap"
|
||||
"net"
|
||||
)
|
||||
|
||||
type UdpServer struct {
|
||||
ServerAddr string `json:"server_addr" required:"true" placeholder:"0.0.0.0:8080 or :8080" zh_name:"监听地址"`
|
||||
gp *ants.PoolWithFunc
|
||||
packetConn net.PacketConn
|
||||
handlers map[string]handler.Handler
|
||||
}
|
||||
|
||||
type udpPacket struct {
|
||||
n int
|
||||
buf []byte
|
||||
addr net.Addr
|
||||
}
|
||||
|
||||
func (us *UdpServer) Init() error {
|
||||
us.handlers = make(map[string]handler.Handler, 0)
|
||||
if err := us.listen(); err != nil {
|
||||
return err
|
||||
}
|
||||
var err error
|
||||
us.gp, err = ants.NewPoolWithFunc(1000000, func(i interface{}) {
|
||||
p := i.(*udpPacket)
|
||||
defer bp.Put(p.buf)
|
||||
|
||||
logger.Debug("accept a now packet", zap.String("remote addr", p.addr.String()))
|
||||
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (us *UdpServer) GetServerAddr() string {
|
||||
if us.packetConn == nil {
|
||||
return us.ServerAddr
|
||||
}
|
||||
return us.packetConn.LocalAddr().String()
|
||||
}
|
||||
|
||||
func (us *UdpServer) GetName() string {
|
||||
return "udp"
|
||||
}
|
||||
|
||||
func (us *UdpServer) GetZhName() string {
|
||||
return "udp服务"
|
||||
}
|
||||
|
||||
func (us *UdpServer) listen() error {
|
||||
addr, err := net.ResolveUDPAddr("udp", us.ServerAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
us.packetConn, err = net.ListenUDP("udp", addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (us *UdpServer) Serve() {
|
||||
for {
|
||||
buf := bp.Get()
|
||||
n, addr, err := us.packetConn.ReadFrom(buf)
|
||||
if err != nil {
|
||||
logger.Error("accept packet failed", zap.Error(err))
|
||||
break
|
||||
}
|
||||
err = us.gp.Invoke(udpPacket{n: n, buf: buf, addr: addr})
|
||||
if err != nil {
|
||||
logger.Error("Invoke error", zap.Error(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user