QuickFixN会话断开事件未调用OnLogout及连接失败日志问题排查
咱们先把问题的核心理清楚:QuickFix/N的OnLogout方法可不是随便触发的——它只在FIX协议层面完成正规Logout流程时才会被调用,不管是你主动发Logout消息,还是收到对方发来的Logout消息。但你日志里记录的都是TCP连接层面的异常,这种情况框架根本没机会走FIX的Logout流程,自然不会触发OnLogout。
结合你的日志内容,给你几个具体的排查和解决方向:
1. 换用OnDisconnect处理TCP层异常断开
你的日志里全是TCP连接超时、重连失败的记录:
20180418-13:30:51.268 : 连接失败:连接尝试失败,因为连接方在一段时间后未正确响应,或已建立的连接失败,因为连接主机未响应 #.#.#.#:#;
20180418-13:31:00.288 : 正在连接到#.#.#.#的#端口;
20180418-13:31:21.293 : 连接失败:连接尝试失败,因为连接方在一段时间后未正确响应,或已...
这种TCP层的失联/连接失败,框架会触发OnDisconnect方法——这个方法才是专门处理所有连接断开场景(不管正常还是异常)的回调。你可以把原来想在OnLogout里做的会话清理、状态通知逻辑,放到OnDisconnect里执行。
2. 优化心跳与超时配置,让框架更快检测异常
如果是已建立连接后突然失联,可能是心跳参数设置得太宽松,导致框架没能及时发现连接异常。你可以检查FIX配置文件里的这几个关键参数:
HeartBtInt:心跳间隔,建议设为30-60秒,太短容易产生无效心跳,太长会延迟异常检测MaxLatency:最大延迟时间,超过这个时长没收到对方心跳,就判定会话失效ReconnectInterval:重连间隔,避免短时间内频繁重连导致资源浪费
合理调整这些参数,能让框架更快感知到连接异常,及时触发OnDisconnect。
3. 在重连失败后手动处理会话收尾
你的日志显示框架在自动重连,要是重连多次都失败,你可能需要触发类似Logout的收尾逻辑。可以这么做:
- 在配置里设置
MaxReconnectAttempts,指定最大重连次数 - 监听
OnLogonFailed事件,或者在OnDisconnect里判断当前重连次数是否达到上限,达到后手动执行会话清理代码,比如:
public override void OnDisconnect() { base.OnDisconnect(); // 检查是否已达到最大重连次数 if (SessionSettings.GetInt("MaxReconnectAttempts") <= SessionState.ReconnectAttempts) { // 执行类似OnLogout的收尾逻辑 ClearSessionState(); NotifySystemSessionLost(); } }
总结
你遇到的本质是TCP层异常≠FIX协议层Logout,所以OnLogout不会被触发。改用OnDisconnect处理这类场景,再配合优化心跳超时配置、处理重连失败后的收尾,就能解决你的问题啦。
内容的提问来源于stack exchange,提问作者rupweb

