在QuickFIX接受器中自定义FIX登录过程

时间:2010-08-27 09:16:06

标签: c# quickfix fix-protocol

我正在使用QuickFIX和C#来创建一个FIX接受器(服务器)。我希望客户端(FIX启动器)使用用户名和密码登录。但是,我不确定如何在QuickFIX中做到这一点。

通过调试QuickFIX源代码,我发现了以下事件序列:

  • QuickFIX将调用Session::verify来验证登录。
  • Session::verify将对comp ID和序列号等内容进行各种检查,并在某些时候确定收到的登录是否有效。
  • Session::verify然后会调用Application::fromAdmin回调,我认为这是自定义登录等内容的自然场所。
  • 但是,此时QuickFIX已经确定登录是正常的,并且当回调返回时,接受者将返回相应的登录消息。

如何在接受器中自定义FIX登录过程?修改QuickFIX代码是我唯一的选择吗?

3 个答案:

答案 0 :(得分:6)

如果您使用的是FIX 4.3或更高版本,则Logon消息可以包含Password标记。如果您使用的是以前的版本,请将其设为自定义标记并将其添加到词典中。

fromAdmin处理程序中,检查密码是否正确(从查找表或其他位置)。如果不是,请抛出RejectLogon例外。如果不抛出此异常,QuickFix将假设一切正常并将用户登录。

示例(需要更多健全性检查):

public void fromAdmin(Message message, SessionID id)
{
   var logon = message as QuickFix44.Logon;

   if (logon != null)
   {
      string userName = logon.getUserName().getValue();
      string expectedPassword = PasswordsByUser[userName];

      string suppliedPassword = logon.getPassword().getValue();

      if(expectedPassword != suppliedPassword)
          throw new RejectLogon();
   }     
}

答案 1 :(得分:1)

  

fromAdmin会在从交易对手向您的FIX引擎发送管理消息时通知您。这对于对登录消息进行额外验证(例如检查密码)非常有用。抛出RejectLogon异常将断开交易对手的连接。

会话验证通常是FIX Begin String,SenderCompID和目标CompID的ckecks。如果这3个很好,则会话设置(QuickFIXJ还有子组件的其他字段)。

即使在设置了会话之后,也不会在接受者处接受该特定会话的消息,直到登录过程完成为止。如果您这样做,您将获得拒绝。

因此,在fromAdmin中,您可以检查传入的登录消息请求,并检查登录消息中包含的有效密码,您希望该连接/会话。

答案 2 :(得分:1)

抛出RejectLogon QuickFIXException会破坏整个代码并中断其余的会话(如果你有多个会话)。 在我自己的情况下,我撰写了一个注销消息并将其发送回交易对手。代码将是这样的:

public void fromAdmin(Message message, SessionID id)
{
   var logon = message as QuickFix44.Logon;

   if (logon != null)
   {
      string userName = logon.getUserName().getValue();
      string expectedPassword = PasswordsByUser[userName];

      string suppliedPassword = logon.getPassword().getValue();

      if(expectedPassword != suppliedPassword)
          {
                Message _logoutmess = new Message();
                _logoutmess.Header.SetField(new MsgType() { Tag = 35, Obj = "5" });
                _logoutmess.SetField(new Text("Invalid credentials"));
                Session.SendToTarget(_logoutmess, id);
          }
   }     
}