package protocol import ( "encoding/json" "errors" "fmt" "git.noahlan.cn/noahlan/nnet/core" "git.noahlan.cn/noahlan/nnet/entity" "git.noahlan.cn/noahlan/nnet/packet" "git.noahlan.cn/noahlan/ntools-go/core/nlog" ) type OnReadyFunc func() func WithNNetClientPipeline(onReady OnReadyFunc, packer packet.Packer) core.RunOption { return func(server *core.NNet) { server.Pipeline().Inbound().PushFront(func(entity entity.NetworkEntity, v interface{}) error { pkg, ok := v.(*NNetPacket) if !ok { return ErrWrongPacketType } conn, _ := entity.Conn() // Server to client switch pkg.PacketType { case Handshake: var handshakeData HandshakeResp err := json.Unmarshal(pkg.Data, &handshakeData) nlog.Must(err) hrd, _ := packer.Pack(Header{ PacketType: HandshakeAck, MessageHeader: MessageHeader{}, }, nil) if err := entity.SendBytes(hrd); err != nil { return err } entity.SetStatus(core.StatusWorking) // onReady if onReady != nil { onReady() } nlog.Debugf("connection handshake Id=%d, Remote=%s", entity.Session().ID(), conn.RemoteAddr()) case Kick: _ = entity.Close() case Data: status := entity.Status() if status != core.StatusWorking { return errors.New(fmt.Sprintf("receive data on socket which not yet ACK, session will be closed immediately, remote=%s", conn.RemoteAddr())) } var lastMid uint64 switch pkg.MsgType { case Response: lastMid = pkg.ID case Notify: lastMid = 0 } entity.SetLastMID(lastMid) } return nil }) } }