简体   繁体   English

如何让我的服务 object 等到它在 Spring 启动中收到来自外部资源的响应

[英]How to make my service object to wait till it receives respond from external resource in Spring boot

I am implementing a client application to automate trading tasks in InteractiveBroker(IB) platform.我正在实施一个客户端应用程序以在 InteractiveBroker(IB) 平台中自动执行交易任务。 They are providing us with standalone application called TradingWorkStation(TWS) and a library to implement our own client applications.他们为我们提供了名为 TradingWorkStation(TWS) 的独立应用程序和一个库来实现我们自己的客户端应用程序。 But our client application cannot directly communicate with IB platform on its own, client app has to pass our message to TWS application and TWS handles the communication with the actual IB platform.但是我们的客户端应用程序本身不能直接与IB平台通信,客户端应用程序必须将我们的消息传递给TWS应用程序,TWS处理与实际IB平台的通信。

IB library provides us with EClientSocket interface, which has methods to communicate with TWS application. IB 库为我们提供了 EClientSocket 接口,该接口具有与 TWS 应用程序通信的方法。 But they are asynchronous calls with no responses.但它们是没有响应的异步调用。 When TWS needs to send back responses, it calls EWrapper interface of client application.当 TWS 需要发回响应时,它会调用客户端应用程序的 EWrapper 接口。

Refer to following diagram,参考下图,

在此处输入图像描述

I am using Spring Boot to develop this client application.我正在使用 Spring Boot 来开发这个客户端应用程序。 I have TraderService class which has eClient object as a attribute to communicate with TWS app.我有 TraderService class,它具有 eClient object 作为与 TWS 应用程序通信的属性。 And I need to ask for contract details from TWS to initiate the trading process.我需要向 TWS 索取合约细节以启动交易流程。 I need TraderService constructor to continue only of these requested contract details are available.我需要 TraderService 构造函数来继续只有这些请求的合同详细信息可用。

Refer to TraderService below,请参阅下面的 TraderService,

@Service
public class TraderService {
    private final IBEventWrapper eventWrapper;
    private final EClientSocket socket;

    public TraderService() {
        
        this.eventWrapper = new IBEventWrapper();

        this.socket = new EClientSocket(eventWrapper);
        socket.eConnect('localhost', 7497, 1);

        if (socket.isConnected()) {
            logger.info("connected..");
            
            // requesting contract details, but return type is void
            socket.reqContractDetails();

           // continue only if contract results are available ...
        }
    }
}

Notice here, reqContractDetails method does not have a return type, and actual results are received to EWrapper interface implementation.注意这里, reqContractDetails方法没有返回类型,实际结果接收到 EWrapper 接口实现。

Refer to EWrapper implementatin below,请参阅下面的 EWrapper 实现,

public class IBEventWrapper implements EWrapper {
    private final TraderService traderService;

    public IBEventWrapper(TraderService traderService) {
        // trying to pass results back to trader service
        this.traderService = traderService;
    }
    
    // this method is invoked by TWS to return contract results
    @Override
    public void contractDetails(int reqId, ContractDetails contractDetails) {
        logger.info("contractDetails {}", reqId);
    }
}

As seen above, EWrapper methods are invoked by TWS app, when results are available.如上所示,当结果可用时,TWS 应用程序调用 EWrapper 方法。 But I need to pass them back to TraderService constructor.但我需要将它们传递回 TraderService 构造函数。

Is there any approach (may be from Spring boot) to make this happen.是否有任何方法(可能来自 Spring 引导)来实现这一点。

IB TWS API is publish–subscribe based, you will have to make requests and await data to return. IB TWS API 是基于发布-订阅的,您必须发出请求并等待数据返回。 I have been using CountDownLatch like this (in your handler class):我一直在使用这样的CountDownLatch (在您的处理程序类中):

  private CountDownLatch latch = new CountDownLatch(1);

  public String getGenericTick() {
    return genericTick;
  }

  public CountDownLatch getLatch() {
    return latch;
  }

  @Override
  public void tickString(TickType tickType, String value) {
    if (tickType == TickType.FUNDAMENTAL_RATIOS) {
      genericTick = value;
      latch.countDown();
    }
  }

Which allows you to know if the data is available or explicitly await for some time (3s is usually enough for anything within a single request):这使您可以知道数据是否可用或显式等待一段时间(3s 通常足以处理单个请求中的任何内容):

  var handler = new FundamentalsRatiosDataHandler();

  controller.reqTopMktData(contract, "258", false, false, handler);
    if (!handler
        .getLatch()
        .await(3, TimeUnit.SECONDS)) {
      // failure
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在Spring Boot中,我有一个异步调用,我必须等待下一个线程等待直到CRUD操作 - In Spring Boot i have a Async call and I have to wait my next thread to wait till CRUD Operation 如何使Spring Boot从资源中看到我的图像 - How to make Spring Boot see my images from resources 如何在Spring中从外部jar导入资源? - How to import a resource from external jar in Spring? 如何让节点等到拓扑被定义 - How to make nodes wait till the topology is defined 如何使Callable等到执行? - How to make Callable wait till execution? 如何在 Spring Boot 中通过本机库正确连接到外部服务 - How to properly connect to external service via native library in Spring Boot 如何在spring boot中做出对象的响应 - How to make response of the object in spring boot 如何让Selenium Web驱动程序等到我的firefox插件完成执行 - How to make selenium web driver wait till my firefox plugin is finished executing 如何在 Spring 引导中使用 restTemplate 检索资源 object? - How do I retrieve Resource object using restTemplate in Spring Boot? 如何让服务器的外部 IP 地址可以访问 Spring Boot 应用程序? - How to make Spring Boot application accessible by external IP address of the server?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM