QuickFIX/n FIX协议Acceptor能否动态对接未知Initiator并创建会话?
我刚接触FIX协议,使用版本为1.11.0的QuickFIX/n库,同时使用同版本的QuickFIXn.FIX5.0SP2和QuickFIXn.FIXT1.1组件。
Acceptor配置
[DEFAULT] BeginString=FIXT.1.1 DefaultApplVerID=FIX.5.0SP2 HeartBtInt=20 AppDataDictionary=../../../ApplicationData/FIXRTv1.xml TransportDataDictionary=../../../ApplicationData/FIXT11.xml FileLogPath=log SocketAcceptPort=9823 SocketAcceptHost = 127.0.0.1 ConnectionType=acceptor UseDataDictionary=Y ResetOnLogon=Y ResetOnLogout=Y ResetOnDisconnect=Y SenderCompID=TEST StartTime=00:00:00 EndTime=23:59:00 FileStorePath=store
Initiator配置
[DEFAULT] BeginString=FIXT.1.1 DefaultApplVerID=FIX.5.0SP2 ConnectionType=initiator HeartBtInt=20 AppDataDictionary=../../spec/fix/FIXRTv1.xml TransportDataDictionary=../../spec/fix/FIXT11.xml UseDataDictionary=Y ResetOnLogon=Y ResetOnLogout=Y ResetOnDisconnect=Y FileStorePath=store FileLogPath=log [SESSION] SenderCompID=USER TargetCompID=TEST SocketConnectHost=127.0.0.1 SocketConnectPort=9823 StartTime=00:00:00 EndTime=23:59:00
目前Acceptor配置仅含DEFAULT段时,Initiator会报错:Connection failed: The connection was not established because The destination computer rejected the connection request. 127.0.0.1:9823,只有给Acceptor添加对应Initiator的SESSION段后才能正常连接。
请问Acceptor能否对接预先未知的Initiator并动态创建会话?
QuickFIX/n的Acceptor支持对接预先未知的Initiator并动态创建会话,无需在配置文件中预先定义所有SESSION段,具体实现方式如下:
自定义会话工厂
实现IAcceptorSessionFactory接口,在收到未知Initiator的登录请求时,根据登录消息里的SenderCompID、TargetCompID等字段,动态生成对应会话的配置参数,再创建会话实例。这种方式能灵活控制每个动态会话的参数,是官方推荐的实现方式。关闭严格会话校验
默认情况下QuickFIX/n会校验连接的会话是否存在于配置中,你可以通过代码或配置关闭该校验逻辑,允许未知会话连接。但这种方式灵活性较低,不如自定义会话工厂可控。保持参数一致性
动态创建会话时,需确保会话核心参数(如心跳间隔、数据字典路径、存储/日志路径)与DEFAULT段配置一致,或根据业务需求调整;同时要处理好会话的持久化,避免服务重启后丢失动态会话信息。
以下是简单的C#代码示例:
public class DynamicAcceptorSessionFactory : IAcceptorSessionFactory { private readonly SessionSettings _settings; private readonly IMessageStoreFactory _storeFactory; private readonly ILogFactory _logFactory; private readonly IApplication _application; public DynamicAcceptorSessionFactory(SessionSettings settings, IMessageStoreFactory storeFactory, ILogFactory logFactory, IApplication application) { _settings = settings; _storeFactory = storeFactory; _logFactory = logFactory; _application = application; } public Session CreateSession(SessionID sessionID) { // 检查会话是否已配置,未配置则动态生成 if (!_settings.HasSession(sessionID)) { // 读取DEFAULT段的基础配置 var defaultConfig = _settings.Get(); // 构建新会话的配置 var sessionConfig = new Dictionary<string, string>(defaultConfig) { ["SenderCompID"] = sessionID.SenderCompID, ["TargetCompID"] = sessionID.TargetCompID }; // 将新会话配置加入全局设置 _settings.Set(sessionID, sessionConfig); } return SessionFactory.Create(sessionID, _application, _storeFactory, _logFactory, _settings); } }
初始化Acceptor时使用自定义工厂:
var settings = new SessionSettings("acceptor.cfg"); var application = new YourCustomApplication(); var storeFactory = new FileStoreFactory(settings); var logFactory = new FileLogFactory(settings); var sessionFactory = new DynamicAcceptorSessionFactory(settings, storeFactory, logFactory, application); var acceptor = new ThreadedSocketAcceptor(application, storeFactory, settings, logFactory, sessionFactory); acceptor.Start();
通过上述实现,Acceptor即可接收预先未知的Initiator连接,并动态创建对应的会话。
内容的提问来源于stack exchange,提问作者rapetum228

