func (s *Session) run(msgIn chan fixIn, quit chan bool) { defer func() { close(quit) s.messageOut <- nil s.onDisconnect() }() if s.initiateLogon { if s.resetOnLogon { s.store.Reset() } logon := NewMessageBuilder() logon.Header().Set(field.NewMsgType("A")) logon.Header().Set(field.NewBeginString(s.sessionID.BeginString)) logon.Header().Set(field.NewTargetCompID(s.sessionID.TargetCompID)) logon.Header().Set(field.NewSenderCompID(s.sessionID.SenderCompID)) logon.Body().Set(field.NewEncryptMethod(0)) logon.Body().Set(field.NewHeartBtInt(s.heartBtInt)) s.heartBeatTimeout = time.Duration(s.heartBtInt) * time.Second if len(s.defaultApplVerID) > 0 { logon.Body().Set(field.NewDefaultApplVerID(s.defaultApplVerID)) } s.log.OnEvent("Sending logon request") s.send(logon) } for { switch s.currentState.(type) { case latentState: return } select { case fixIn, ok := <-msgIn: if ok { s.log.OnIncoming(string(fixIn.bytes)) if msg, err := parseMessage(fixIn.bytes); err != nil { s.log.OnEventf("Msg Parse Error: %v, %q", err.Error(), fixIn.bytes) } else { msg.ReceiveTime = fixIn.receiveTime s.currentState = s.currentState.FixMsgIn(s, *msg) } } else { return } s.peerTimer.Reset(time.Duration(int64(1.2 * float64(s.heartBeatTimeout)))) case msg := <-s.toSend: s.send(msg) case <-quit: return case evt := <-s.sessionEvent: s.currentState = s.currentState.Timeout(s, evt) } } }
func (s *Session) handleLogon(msg Message) error { //Grab default app ver id from fixt.1.1 logon if s.sessionID.BeginString == fix.BeginString_FIXT11 { targetApplVerID := &field.DefaultApplVerIDField{} if err := msg.Body.Get(targetApplVerID); err != nil { return err } s.targetDefaultApplVerID = targetApplVerID.Value } if !s.initiateLogon { s.log.OnEvent("Received logon request") if s.resetOnLogon { s.store.Reset() } resetSeqNumFlag := new(fix.BooleanValue) if err := msg.Body.GetField(tag.ResetSeqNumFlag, resetSeqNumFlag); err == nil { if resetSeqNumFlag.Value { s.log.OnEvent("Logon contains ResetSeqNumFlag=Y, resetting sequence numbers to 1") s.store.Reset() } } if err := s.verifyIgnoreSeqNumTooHigh(msg); err != nil { return err } reply := NewMessageBuilder() reply.Header().Set(field.NewMsgType("A")) reply.Header().Set(field.NewBeginString(s.sessionID.BeginString)) reply.Header().Set(field.NewTargetCompID(s.sessionID.TargetCompID)) reply.Header().Set(field.NewSenderCompID(s.sessionID.SenderCompID)) reply.Body().Set(field.NewEncryptMethod(0)) heartBtInt := &field.HeartBtIntField{} if err := msg.Body.Get(heartBtInt); err == nil { s.heartBeatTimeout = time.Duration(heartBtInt.Value) * time.Second reply.Body().Set(heartBtInt) } if resetSeqNumFlag.Value { reply.Body().Set(field.NewResetSeqNumFlag(resetSeqNumFlag.Value)) } if len(s.defaultApplVerID) > 0 { reply.Body().Set(field.NewDefaultApplVerID(s.defaultApplVerID)) } s.log.OnEvent("Responding to logon request") s.send(reply) } s.application.OnLogon(s.sessionID) if err := s.checkTargetTooHigh(msg); err != nil { switch TypedError := err.(type) { case targetTooHigh: s.doTargetTooHigh(TypedError) } } s.store.IncrNextTargetMsgSeqNum() return nil }