You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在代码中获取QuickFIX/J的入站/出站/心跳消息?

获取QuickFIX/J 1.6.4中的入站、出站及心跳消息

当然可以!在QuickFIX/J中,你完全可以通过代码拦截并处理入站、出站消息,以及作为会话核心的心跳消息。核心思路是利用框架提供的Application接口,它定义了消息流转各阶段的回调方法,下面是具体实现方案:

1. 核心实现:自定义Application类

Application是QuickFIX/J的核心扩展点,其中的方法对应不同类型的消息处理场景:

  • fromApp():处理入站应用级业务消息(比如订单请求、成交回报等)
  • toApp():拦截出站应用级业务消息(发送前可修改或阻止)
  • fromAdmin():处理入站会话级消息(包含心跳、登录请求等)
  • toAdmin():拦截出站会话级消息(包含心跳、登出请求等)

基础代码示例

import quickfix.Application;
import quickfix.DoNotSend;
import quickfix.FieldNotFound;
import quickfix.Message;
import quickfix.SessionID;
import quickfix.field.MsgType;

public class CustomFixHandler implements Application {

    @Override
    public void onCreate(SessionID sessionId) {
        // 会话创建时触发,可做初始化操作
    }

    @Override
    public void onLogon(SessionID sessionId) {
        System.out.println("会话已登录: " + sessionId);
    }

    @Override
    public void onLogout(SessionID sessionId) {
        System.out.println("会话已登出: " + sessionId);
    }

    // 处理入站应用消息
    @Override
    public void fromApp(Message message, SessionID sessionId) throws FieldNotFound {
        String msgType = message.getHeader().getString(MsgType.FIELD);
        System.out.println("[入站应用消息] 类型: " + msgType + " | 会话: " + sessionId);
        // 这里可根据消息类型做业务逻辑处理
    }

    // 拦截出站应用消息
    @Override
    public void toApp(Message message, SessionID sessionId) throws DoNotSend {
        String msgType = message.getHeader().getString(MsgType.FIELD);
        System.out.println("[出站应用消息] 类型: " + msgType + " | 会话: " + sessionId);
        // 若需阻止消息发送,抛出DoNotSend异常即可
    }

    // 处理入站会话消息(含心跳)
    @Override
    public void fromAdmin(Message message, SessionID sessionId) throws FieldNotFound {
        String msgType = message.getHeader().getString(MsgType.FIELD);
        if (MsgType.HEARTBEAT.equals(msgType)) {
            System.out.println("[入站心跳] 会话: " + sessionId);
        } else {
            System.out.println("[入站会话消息] 类型: " + msgType + " | 会话: " + sessionId);
        }
    }

    // 拦截出站会话消息(含心跳)
    @Override
    public void toAdmin(Message message, SessionID sessionId) {
        String msgType = message.getHeader().getString(MsgType.FIELD);
        if (MsgType.HEARTBEAT.equals(msgType)) {
            System.out.println("[出站心跳] 会话: " + sessionId);
        } else {
            System.out.println("[出站会话消息] 类型: " + msgType + " | 会话: " + sessionId);
        }
    }
}

2. 更优雅的消息拆分:使用MessageCracker

如果需要针对特定消息类型(比如心跳、测试请求、订单等)编写单独的处理逻辑,可以继承MessageCracker类,它会自动根据消息类型(MsgType)分发到对应的处理方法,避免大量的if-else判断:

import quickfix.Application;
import quickfix.FieldNotFound;
import quickfix.Message;
import quickfix.SessionID;
import quickfix.MessageCracker;
import quickfix.fix42.Heartbeat;
import quickfix.fix42.TestRequest;

public class CrackingFixHandler extends MessageCracker implements Application {

    @Override
    public void onCreate(SessionID sessionId) {}

    @Override
    public void onLogon(SessionID sessionId) {}

    @Override
    public void onLogout(SessionID sessionId) {}

    @Override
    public void fromApp(Message message, SessionID sessionId) throws FieldNotFound {
        crack(message, sessionId); // 交给MessageCracker自动分发
    }

    @Override
    public void toApp(Message message, SessionID sessionId) throws DoNotSend {}

    @Override
    public void fromAdmin(Message message, SessionID sessionId) throws FieldNotFound {
        crack(message, sessionId); // 会话消息也可通过Cracker处理
    }

    @Override
    public void toAdmin(Message message, SessionID sessionId) {}

    // 专门处理心跳消息的方法
    public void onMessage(Heartbeat heartbeat, SessionID sessionId) throws FieldNotFound {
        System.out.println("[心跳消息] 会话: " + sessionId);
    }

    // 可添加其他消息类型的处理方法
    public void onMessage(TestRequest testRequest, SessionID sessionId) throws FieldNotFound {
        System.out.println("[测试请求] 会话: " + sessionId);
    }
}

3. 关键注意事项

  • 心跳属于会话级消息(Admin Message),所以要在fromAdmin和toAdmin中处理,fromApp/toApp是用来处理业务级应用消息的。
  • 如果需要修改出站消息(比如添加自定义字段),直接在toApp或toAdmin中操作Message对象即可。
  • 若要取消某条消息的发送,在toApp方法中抛出DoNotSend异常即可。

内容的提问来源于stack exchange,提问作者Sakshi Singla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 11:01:51