package core import ( "encoding/json" "errors" "fmt" "git.noahlan.cn/northlan/nnet/internal/log" "git.noahlan.cn/northlan/nnet/internal/packet" "time" ) var ( hrd []byte // handshake response data hbd []byte // heartbeat packet data ) type NNetProcessor struct { } func NewNNetProcessor() *NNetProcessor { // TODO custom hrd hbd data, _ := json.Marshal(map[string]interface{}{ "code": 200, "sys": map[string]float64{"heartbeat": time.Second.Seconds()}, }) packer := packet.NewNNetPacker() hrd, _ = packer.Pack(packet.Handshake, data) return &NNetProcessor{} } func (n *NNetProcessor) Process(conn *Connection, p packet.IPacket) error { h, ok := p.(*packet.Packet) if !ok { return packet.ErrWrongPacketType } switch h.PacketType { case packet.Handshake: // TODO validate handshake if err := conn.SendBytes(hrd); err != nil { return err } conn.SetStatus(StatusPrepare) log.Debugf("connection handshake Id=%d, Remote=%s", conn.ID(), conn.Conn().RemoteAddr()) case packet.HandshakeAck: conn.SetStatus(StatusPending) log.Debugf("receive handshake ACK Id=%d, Remote=%s", conn.ID(), conn.Conn().RemoteAddr()) case packet.Heartbeat: // Expected case packet.Data: if conn.Status() < StatusPending { return errors.New(fmt.Sprintf("receive data on socket which not yet ACK, session will be closed immediately, remote=%s", conn.Conn().RemoteAddr())) } conn.SetStatus(StatusWorking) var lastMid uint64 switch h.MsgType { case packet.Request: lastMid = h.ID case packet.Notify: lastMid = 0 default: return fmt.Errorf("Invalid message type: %s ", h.MsgType.String()) } conn.SetLastMID(lastMid) } conn.SetLastHeartbeatAt(time.Now().Unix()) return nil }