当QuickFix / J无法连接时,如何避免自动重新连接?

时间:2016-09-23 18:43:39

标签: quickfix quickfixj

想象一下连接IP无法访问的场景。在这种情况下,QuickFIX / J将尝试每30秒左右自动重新连接,由参数ReconnectInterval配置。我该如何避免这种行为?

2 个答案:

答案 0 :(得分:1)

您的应用程序类应该扩展ApplicationExtended而不是Application。然后你可以覆盖canLogon方法,如果你返回false,Quickfixj将不会尝试登录。

答案 1 :(得分:0)

这个想法包括从QuickFix / J中检索参数ReconnectInterval并创建一个单独的线程,当且仅当Session尚未登录时才会终止Session

为了使其工作,我们的线程显然必须在QuickFix / J线程尝试重新连接之前触发。换句话说:如果你配置了ReconnectInterval=30 ...你必须在此之前触发上述线程并关闭所有启动器。这样,QuickFix / J最终不会重新尝试重新连接。

import java.io.InputStream
import java.util.Locale
import scala.util.control.NonFatal
import quickfix._
import quickfix.field._

class SimpleConnection(val configInputStream: InputStream,
                       val messageFactory: quickfix.MessageFactory)
  extends MessageCracker
    with quickfix.Application {

  private val locale = Locale.getDefault.getCountry
  private val settings = new SessionSettings(configInputStream)
  private val storeFactory = new FileStoreFactory(settings)
  private val loggerFactory = new QuickfixLoggerFactory(settings)

  private var initiatorOption: Option[SocketInitiator] = None
  private var sessionOption  : Option[SessionID] = None
  private var senderSeqOption: Option[Int] = None
  private var targetSeqOption: Option[Int] = None

  override def onLogout(sessionId: SessionID): Unit = {
    log.info("onLogout called for %s".format(sessionId))
    initiatorOption.foreach(initiator => initiator.stop(true))
    fireDisconnectedState // inform listeners
    initiatorOption = None
    sessionOption = None
  }

  override def onCreate(sessionId: SessionID): Unit = {
    log.info("onCreate called for %s".format(sessionId))

    val session = Session.lookupSession(sessionId)
    val interval = settings.getLong(session.getSessionID, "ReconnectInterval")

    if(interval <= 10)
      log.error("ReconnectInterval should be at least 10secs.")
    else {
      import java.util.concurrent.Executors
      import scala.concurrent.ExecutionContext
      val executor = ExecutionContext.fromExecutor(Executors.newSingleThreadExecutor)
      val monitor = new Runnable {
        override def run(): Unit = {
          val sleep = (interval-5)*1000
          Thread.sleep(sleep)
          if(!session.isLoggedOn) {
            log.warn("Killing QuickFix/J session before reconnection.")
            onLogout(session.getSessionID)
          }
        }
      }
      executor.execute(monitor)
    }

    senderSeqOption.foreach(session.setNextSenderMsgSeqNum(_))
    targetSeqOption.foreach(session.setNextTargetMsgSeqNum(_))

    senderSeqOption = None
    targetSeqOption = None
  }

}