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" "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) 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) { } 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 } packets, err := h.server.Packer.Unpack(buf) 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.lastHeartbeatAt = time.Now().Unix() return err }