Vertx EventBus回复“特定”消息

时间:2018-10-02 09:44:18

标签: rest vert.x event-bus

我们有以下情况:

enter image description here

担心的是,协调器从方法上下文中发送一条消息并从另一个上下文中获取响应:

private void forwardToVWClient(Message msg) {

        vertx.eventBus().send(RESTClient.ADDRESS, msg.body(), deliveryOptions, res -> {
            if (res.succeeded()) {
                log.info("forwardToVWClient. VW got result : success.");
                // do not reply ok until we get an OK from the Listener verticle

            } else {
                log.error("forwardToVWClient VW got result : failure.");
                msg.fail(500, res.cause().getMessage());
            }
        });
    }

然后我有另一种消耗事件总线的方法,可以在其中接收响应:

vertx.eventBus().consumer(ADDRESS_RESPONSE, this::handleResponseMessage);


private void handleResponseMessage(Message msg) {
        // how to reply the message received in the context of forwardToVWClient ?? 
}

因此,当我在forwardToVWClient中收到响应时,如何在handleResponseMessage的上下文中回复消息?

到目前为止的想法:

  1. 将消息放入vertx上下文中?
  2. 消息对象具有一个字段:.replyAddress(),它返回一个int值,我将其保存在静态ConcurrentHashMap中,并使用它来回复特定消息。我将发布更多详细信息作为答案。

有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

一种实现方法是保存邮件的replyAddress字段,然后使用该字段将邮件发送回原始发件人。

下面是一些简化的代码,显示了如何:

public class VehicleStateCoordinatorVerticle extends AbstractVerticle {


    final static String ADDRESS_REQUEST = "CoordinatorRequest";
    final static String ADDRESS_RESPONSE = "CoordinatorResponse";

    static ConcurrentHashMap<String, VWApiRequest> pendingCommands = new ConcurrentHashMap<>();


    public void start() {
        vertx.eventBus().consumer(ADDRESS_REQUEST, this::handleRequestMessage);
        vertx.eventBus().consumer(ADDRESS_RESPONSE, this::handleResponseMessage);
        log.info("===== VehicleStateCoordinatorVerticle - bus consumer ready =====");
    }

    private void handleRequestMessage(Message msg) {

            // .... omitted for brevity
            // save the replyAddress and the command for later/callback
            cmd.setReplyAddress(msg.replyAddress());
            pendingCommands.put(cmd.getVwReference(), cmd);


            forwardToVWClient(msg);
    }


    private void forwardToVWClient(Message msg) {

        vertx.eventBus().send(AbstractOEMClientVerticle.ADDRESS, msg.body(), deliveryOptions, res -> {
            if (res.succeeded()) {
                log.info("forwardToVWClient. VW got result : success.");
                // do not reply ok until we get an OK from the VWAPIServer verticle

            } else {
                log.error("forwardToVWClient VW got result : failure.");
                msg.fail(500, res.cause().getMessage());
            }
        });
    }



    private void handleResponseMessage(Message msg) {

        //..
        VWApiRequest vwApiRequest = pendingCommands.get(vwReference);
        if(vwApiRequest == null){
            log.error("No pending vwApiRequest could be found!");
            return;
        }

        /**
         * Instead of targeting the RESTApi address,
         * we use the replyAddress to target the specific message that is pending response.
         */
        vertx.eventBus().send(vwApiRequest.getReplyAddress(), body, deliveryOptions, res -> {
            if (res.succeeded()) {
             // cheers!
            }
            else{
                log.error("Error in handleResponseMessage {}", res.cause().getMessage());
            }

        });
    }