|
|
package nnet
|
|
|
|
|
|
import (
|
|
|
"fmt"
|
|
|
"git.noahlan.cn/northlan/nnet/component"
|
|
|
"git.noahlan.cn/northlan/nnet/log"
|
|
|
"git.noahlan.cn/northlan/nnet/packet"
|
|
|
"git.noahlan.cn/northlan/nnet/pipeline"
|
|
|
"github.com/gorilla/websocket"
|
|
|
"net"
|
|
|
"time"
|
|
|
)
|
|
|
|
|
|
type Handler struct {
|
|
|
server *Server // Server 引用
|
|
|
pipeline pipeline.Pipeline // 通道
|
|
|
processor packet.Processor // 数据包处理器
|
|
|
|
|
|
allServices map[string]*component.Service // 所有注册的Service
|
|
|
allHandlers map[string]*component.Handler // 所有注册的Handler
|
|
|
}
|
|
|
|
|
|
func NewHandler(server *Server, pipeline pipeline.Pipeline, processor packet.Processor) *Handler {
|
|
|
return &Handler{
|
|
|
server: server,
|
|
|
pipeline: pipeline,
|
|
|
processor: processor,
|
|
|
allServices: make(map[string]*component.Service),
|
|
|
allHandlers: make(map[string]*component.Handler),
|
|
|
}
|
|
|
}
|
|
|
|
|
|
func (h *Handler) register(comp component.Component, opts []component.Option) error {
|
|
|
s := component.NewService(comp, opts)
|
|
|
|
|
|
if _, ok := h.allServices[s.Name]; ok {
|
|
|
return fmt.Errorf("handler: service already defined: %s", s.Name)
|
|
|
}
|
|
|
|
|
|
if err := s.ExtractHandler(); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
h.allServices[s.Name] = s
|
|
|
|
|
|
// 拷贝一份所有handlers
|
|
|
for name, handler := range s.Handlers {
|
|
|
handleName := fmt.Sprintf("%s.%s", s.Name, name)
|
|
|
log.Debugf("register handler %s", handleName)
|
|
|
h.allHandlers[handleName] = handler
|
|
|
}
|
|
|
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
func (h *Handler) handleWS(conn *websocket.Conn) {
|
|
|
c, err := newWSConn(conn)
|
|
|
if err != nil {
|
|
|
log.Error(err)
|
|
|
return
|
|
|
}
|
|
|
h.handle(c)
|
|
|
}
|
|
|
|
|
|
func (h *Handler) handle(conn net.Conn) {
|
|
|
connection := newConnection(h.server, conn, h.pipeline)
|
|
|
h.server.sessionMgr.StoreSession(connection.Session())
|
|
|
|
|
|
_ = pool.SubmitConn(func() {
|
|
|
h.writeLoop(connection)
|
|
|
})
|
|
|
|
|
|
_ = pool.SubmitWorker(func() {
|
|
|
h.readLoop(connection)
|
|
|
})
|
|
|
|
|
|
// hook
|
|
|
}
|
|
|
|
|
|
func (h *Handler) writeLoop(conn *Connection) {
|
|
|
conn.write()
|
|
|
}
|
|
|
|
|
|
func (h *Handler) readLoop(conn *Connection) {
|
|
|
buf := make([]byte, 4096)
|
|
|
for {
|
|
|
n, err := conn.Conn().Read(buf)
|
|
|
if err != nil {
|
|
|
log.Errorf("Read message error: %s, session will be closed immediately", err.Error())
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// warning: 为性能考虑,复用slice处理数据,buf传入后必须要copy再处理
|
|
|
packets, err := h.server.Packer.Unpack(buf[:n])
|
|
|
if err != nil {
|
|
|
log.Error(err.Error())
|
|
|
}
|
|
|
// packets 处理
|
|
|
for _, p := range packets {
|
|
|
if err := h.processPackets(conn, p); err != nil {
|
|
|
log.Error(err.Error())
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
func (h *Handler) processPackets(conn *Connection, packets interface{}) error {
|
|
|
err := h.processor.ProcessPacket(conn, packets)
|
|
|
|
|
|
conn.setLastHeartbeatAt(time.Now().Unix())
|
|
|
return err
|
|
|
}
|