Esempio n. 1
0
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)
		}
	}
}
Esempio n. 2
0
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
}