feat 优化网络库
This commit is contained in:
@@ -28,9 +28,9 @@ const (
|
||||
|
||||
// ISocketServer 由应用层实现
|
||||
type ISocketServer interface {
|
||||
OnOpen(ISocketConn) ([]byte, Action) // 开启连接
|
||||
OnHandShake(ISocketConn) // 开始握手
|
||||
OnMessage(ISocketConn, []byte) Action // 收到消息
|
||||
OnOpen(ISocketConn) ([]byte, Action) // 开启连接
|
||||
OnHandShake(ISocketConn, []byte, func(ISocketConn, []byte)) Action // 开始握手
|
||||
OnMessage(ISocketConn, []byte) Action // 收到消息
|
||||
OnPong(ISocketConn)
|
||||
OnClose(ISocketConn, error) Action // 关闭连接
|
||||
OnTick() (time.Duration, Action)
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
|
||||
// WSServer 实现GNet库接口
|
||||
type WSServer struct {
|
||||
gnet.BuiltinEventEngine
|
||||
eng gnet.Engine
|
||||
i socket.ISocketServer
|
||||
logger logging.Logger // 日志
|
||||
@@ -20,29 +19,31 @@ type WSServer struct {
|
||||
unUpgradeConn sync.Map
|
||||
}
|
||||
|
||||
func NewWSServer(i socket.ISocketServer, logger logging.Logger, timeout time.Duration) *WSServer {
|
||||
func NewWSServer(i socket.ISocketServer, logger logging.Logger, upgradeTimeout time.Duration) *WSServer {
|
||||
if i == nil {
|
||||
return nil
|
||||
}
|
||||
return &WSServer{
|
||||
i: i,
|
||||
logger: logger,
|
||||
upgradeTimeout: timeout,
|
||||
upgradeTimeout: upgradeTimeout,
|
||||
unUpgradeConn: sync.Map{},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *WSServer) Run(logger logging.Logger, addr string, multiCore, reusePort, tick, lockOSThread, reuseAddr bool, processNum int) error {
|
||||
func (s *WSServer) Run(addr string, multicore bool, numEventLoop int, tcpNoDelay gnet.TCPSocketOpt, readBufferCap, writeBufferCap int, lockOSThread bool, reusePort, ticker bool, logger logging.Logger) error {
|
||||
return gnet.Run(
|
||||
s,
|
||||
addr,
|
||||
gnet.WithMulticore(multiCore),
|
||||
gnet.WithNumEventLoop(processNum),
|
||||
gnet.WithReusePort(reusePort),
|
||||
gnet.WithTicker(tick),
|
||||
gnet.WithLogger(logger),
|
||||
gnet.WithMulticore(multicore),
|
||||
gnet.WithNumEventLoop(numEventLoop),
|
||||
gnet.WithTCPNoDelay(tcpNoDelay),
|
||||
gnet.WithReadBufferCap(readBufferCap),
|
||||
gnet.WithWriteBufferCap(writeBufferCap),
|
||||
gnet.WithLockOSThread(lockOSThread),
|
||||
gnet.WithReuseAddr(reuseAddr),
|
||||
gnet.WithReusePort(reusePort),
|
||||
gnet.WithTicker(ticker),
|
||||
gnet.WithLogger(logger),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -55,6 +56,9 @@ func (s *WSServer) OnBoot(eng gnet.Engine) gnet.Action {
|
||||
return gnet.None
|
||||
}
|
||||
|
||||
func (s *WSServer) OnShutdown(_ gnet.Engine) {
|
||||
}
|
||||
|
||||
func (s *WSServer) OnOpen(c gnet.Conn) ([]byte, gnet.Action) {
|
||||
ws := &WSConn{
|
||||
Conn: c,
|
||||
@@ -89,67 +93,43 @@ func (s *WSServer) OnClose(c gnet.Conn, err error) (action gnet.Action) {
|
||||
}
|
||||
|
||||
// OnTraffic fires when a local socket receives data from the peer.
|
||||
func (s *WSServer) OnTraffic(c gnet.Conn) (action gnet.Action) {
|
||||
tmp := c.Context()
|
||||
if tmp == nil {
|
||||
s.logger.Errorf("OnTraffic context nil: %v", c)
|
||||
action = gnet.Close
|
||||
return
|
||||
}
|
||||
|
||||
ws, ok := tmp.(*WSConn)
|
||||
if !ok {
|
||||
ws.logger.Errorf("OnTraffic convert ws error: %v", tmp)
|
||||
action = gnet.Close
|
||||
return
|
||||
}
|
||||
|
||||
action = ws.readBytesBuf(c)
|
||||
if action != gnet.None {
|
||||
return
|
||||
func (s *WSServer) OnTraffic(c gnet.Conn) gnet.Action {
|
||||
ws := c.Context().(*WSConn)
|
||||
if action := ws.readBytesBuf(c); action != gnet.None {
|
||||
return action
|
||||
}
|
||||
|
||||
if !ws.isUpgrade {
|
||||
var data []byte
|
||||
data, ok, action = ws.upgrade()
|
||||
if ok {
|
||||
data, action := ws.upgrade()
|
||||
if len(data) > 0 {
|
||||
s.unUpgradeConn.Delete(c.RemoteAddr().String())
|
||||
s.i.OnHandShake(ws)
|
||||
if data != nil {
|
||||
err := ws.Conn.AsyncWrite(data, nil)
|
||||
if err != nil {
|
||||
ws.logger.Errorf("update ws write upgrade protocol error", err)
|
||||
action = gnet.Close
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
msg, err := ws.readWsMessages()
|
||||
if err != nil {
|
||||
ws.logger.Errorf("read ws messages errors", err)
|
||||
return gnet.Close
|
||||
action = gnet.Action(s.i.OnHandShake(ws, data, s.OnHandShakeFinish))
|
||||
}
|
||||
return action
|
||||
}
|
||||
|
||||
if msg != nil {
|
||||
for _, m := range msg {
|
||||
if socket.OpCode(m.OpCode) == socket.OpPong {
|
||||
s.i.OnPong(ws)
|
||||
continue
|
||||
}
|
||||
if socket.OpCode(m.OpCode) == socket.OpClose {
|
||||
return gnet.Close
|
||||
}
|
||||
if socket.OpCode(m.OpCode) == socket.OpPing {
|
||||
continue
|
||||
}
|
||||
a := s.i.OnMessage(ws, m.Payload)
|
||||
if gnet.Action(a) != gnet.None {
|
||||
action = gnet.Action(a)
|
||||
}
|
||||
if msg, err := ws.readWsMessages(); err != nil {
|
||||
ws.logger.Errorf("read ws messages err: %v", err)
|
||||
return gnet.Close
|
||||
} else if msg != nil {
|
||||
for _, m := range msg {
|
||||
if socket.OpCode(m.OpCode) == socket.OpPong {
|
||||
s.i.OnPong(ws)
|
||||
continue
|
||||
}
|
||||
if socket.OpCode(m.OpCode) == socket.OpClose {
|
||||
return gnet.Close
|
||||
}
|
||||
if socket.OpCode(m.OpCode) == socket.OpPing {
|
||||
continue
|
||||
}
|
||||
a := s.i.OnMessage(ws, m.Payload)
|
||||
if gnet.Action(a) != gnet.None {
|
||||
return gnet.Action(a)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
return gnet.None
|
||||
}
|
||||
|
||||
// OnTick fires immediately after the engine starts and will fire again
|
||||
@@ -194,3 +174,14 @@ func (s *WSServer) OnTick() (delay time.Duration, action gnet.Action) {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// OnHandShakeFinish 握手完成
|
||||
func (s *WSServer) OnHandShakeFinish(conn socket.ISocketConn, hsResp []byte) {
|
||||
ws := conn.(*WSConn)
|
||||
if err := ws.Conn.AsyncWrite(hsResp, nil); err != nil {
|
||||
ws.logger.Errorf("OnHandShakeFinish err: %v", err)
|
||||
if err = ws.Close(); err != nil {
|
||||
ws.logger.Errorf("OnHandShakeFinish Close error: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,13 +15,14 @@ import (
|
||||
// WSConn 实现ISocketConn接口
|
||||
type WSConn struct {
|
||||
gnet.Conn
|
||||
buf bytes.Buffer
|
||||
logger logging.Logger
|
||||
isUpgrade bool
|
||||
isClose bool
|
||||
param map[string]interface{}
|
||||
openTime int64
|
||||
remoteAddr string
|
||||
buf bytes.Buffer
|
||||
logger logging.Logger
|
||||
isUpgrade bool // 是否已经升级
|
||||
upgradeResp []byte // 升级响应
|
||||
isClose bool
|
||||
param map[string]interface{}
|
||||
openTime int64 // 开启连接的时间
|
||||
remoteAddr string // 远程ID地址
|
||||
wsMessageBuf
|
||||
}
|
||||
|
||||
@@ -60,11 +61,7 @@ func (w *WSConn) readBytesBuf(c gnet.Conn) gnet.Action {
|
||||
return gnet.None
|
||||
}
|
||||
|
||||
func (w *WSConn) upgrade() (data []byte, ok bool, action gnet.Action) {
|
||||
if w.isUpgrade {
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
func (w *WSConn) upgrade() (data []byte, action gnet.Action) {
|
||||
buf := &w.buf
|
||||
tmpReader := bytes.NewReader(buf.Bytes())
|
||||
oldLen := tmpReader.Len()
|
||||
@@ -83,27 +80,24 @@ func (w *WSConn) upgrade() (data []byte, ok bool, action gnet.Action) {
|
||||
}
|
||||
buf.Next(skipN)
|
||||
if w.logger != nil {
|
||||
w.logger.Errorf("ws upgrade error", err.Error())
|
||||
w.logger.Errorf("ws upgrade err: %v", err.Error())
|
||||
}
|
||||
|
||||
action = gnet.Close
|
||||
return
|
||||
}
|
||||
buf.Next(skipN)
|
||||
if w.logger != nil {
|
||||
w.logger.Infof("ws upgrade success conn upgrade websocket protocol!")
|
||||
}
|
||||
//if w.logger != nil {
|
||||
// w.logger.Infof("ws upgrade success conn upgrade websocket protocol!")
|
||||
//}
|
||||
_ = tempWriter.Flush()
|
||||
data = result.Bytes()
|
||||
ok = true
|
||||
w.isUpgrade = true
|
||||
return
|
||||
}
|
||||
|
||||
func (w *WSConn) readWsMessages() (messages []wsutil.Message, err error) {
|
||||
in := &w.buf
|
||||
//messages, err = wsutil.ReadClientMessage(in, messages)
|
||||
//return
|
||||
for {
|
||||
if w.curHeader == nil {
|
||||
if in.Len() < ws.MinHeaderSize { //头长度至少是2
|
||||
@@ -126,13 +120,8 @@ func (w *WSConn) readWsMessages() (messages []wsutil.Message, err error) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
//in.Next(skipN)
|
||||
|
||||
w.curHeader = &head
|
||||
//err = ws.WriteHeader(&msgBuf.cachedBuf, head)
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
}
|
||||
dataLen := (int)(w.curHeader.Length)
|
||||
if dataLen > 0 {
|
||||
|
||||
Reference in New Issue
Block a user