diff --git a/in_session.go b/in_session.go index 4ebf760d2..325b8f713 100644 --- a/in_session.go +++ b/in_session.go @@ -70,9 +70,9 @@ func (state inSession) handleLogon(session *session, msg Message) (nextState ses func (state inSession) handleLogout(session *session, msg Message) (nextState sessionState) { session.log.OnEvent("Received logout request") - state.generateLogout(session) - session.application.OnLogout(session.sessionID) + session.log.OnEvent("Sending logout response") + state.generateLogout(session) return latentState{} } @@ -247,6 +247,7 @@ func (state inSession) doTargetTooLow(session *session, msg Message, rej targetT } func (state *inSession) initiateLogout(session *session, reason string) (nextState logoutState) { + session.log.OnEvent("Inititated logout request") state.generateLogoutWithReason(session, reason) time.AfterFunc(time.Duration(2)*time.Second, func() { session.sessionEvent <- logoutTimeout }) @@ -278,16 +279,15 @@ func (state *inSession) generateLogout(session *session) { } func (state *inSession) generateLogoutWithReason(session *session, reason string) { - reply := NewMessage() - reply.Header.SetField(tagMsgType, FIXString("5")) - reply.Header.SetField(tagBeginString, FIXString(session.sessionID.BeginString)) - reply.Header.SetField(tagTargetCompID, FIXString(session.sessionID.TargetCompID)) - reply.Header.SetField(tagSenderCompID, FIXString(session.sessionID.SenderCompID)) + logout := NewMessage() + logout.Header.SetField(tagMsgType, FIXString("5")) + logout.Header.SetField(tagBeginString, FIXString(session.sessionID.BeginString)) + logout.Header.SetField(tagTargetCompID, FIXString(session.sessionID.TargetCompID)) + logout.Header.SetField(tagSenderCompID, FIXString(session.sessionID.SenderCompID)) if reason != "" { - reply.Body.SetField(tagText, FIXString(reason)) + logout.Body.SetField(tagText, FIXString(reason)) } - session.send(reply) - session.log.OnEvent("Sending logout response") + session.send(logout) } diff --git a/logout_state.go b/logout_state.go index 9af8c8986..d4811676c 100644 --- a/logout_state.go +++ b/logout_state.go @@ -7,13 +7,25 @@ func (state logoutState) String() string { return "Logout State" } func (s logoutState) IsLoggedOn() bool { return false } func (state logoutState) FixMsgIn(session *session, msg Message) (nextState sessionState) { - return state + var msgType FIXString + if err := msg.Header.GetField(tagMsgType, &msgType); err != nil { + return latentState{} + } + + switch string(msgType) { + //logout + case "5": + session.log.OnEvent("Received logout response") + return latentState{} + default: + return state + } } func (state logoutState) Timeout(session *session, event event) (nextState sessionState) { switch event { case logoutTimeout: - session.log.OnEvent("Timed out waiting for Logout response") + session.log.OnEvent("Timed out waiting for logout response") return latentState{} } diff --git a/session.go b/session.go index 9ba76a56a..bd3fb3656 100644 --- a/session.go +++ b/session.go @@ -307,6 +307,8 @@ func (s *session) handleLogon(msg Message) error { s.log.OnEvent("Responding to logon request") s.send(reply) + } else { + s.log.OnEvent("Received logon response") } s.application.OnLogon(s.sessionID) @@ -561,8 +563,12 @@ func (s *session) run(msgIn chan fixIn, msgOut chan []byte, quit chan bool) { s.peerTimer.Reset(time.Duration(int64(1.2 * float64(s.heartBeatTimeout)))) case <-quit: - return - + quit = nil // prevent infinitly receiving on a closed channel + if state, ok := s.sessionState.(inSession); ok { + s.sessionState = state.initiateLogout(s, "") + } else { + return + } case evt := <-s.sessionEvent: s.sessionState = s.Timeout(s, evt) case <-s.messageEvent: