Vertx,具有阻止回复的事件总线

时间:2018-04-07 10:21:00

标签: java asynchronous vert.x

我有两个Verticle,  一个用于向事件总线发送一些数据,一个用于从事件总线接收数据,然后在一些睡眠后进行回复

我的代码是:

发信人:

public class Sender extends AbstractVerticle{

    @Override
    public void start() throws Exception {
        final EventBus eventBus = this.vertx.eventBus();
        this.vertx.setPeriodic(1000, handler->{
            eventBus.<JsonObject>send("test", new JsonObject().put("d", "d"),this::handle);
        });
    }
    private  void handle(AsyncResult<Message<JsonObject>> result) {
        if(result.succeeded()){
            System.out.println("Answer: "+Thread.currentThread().getName());
            System.out.println(result.result().body());
        } else{
            result.cause().printStackTrace();
        }
    }
}

接收器:

public class Receiver extends AbstractVerticle {

    @Override
    public void start() throws Exception {
        final EventBus eventBus = this.vertx.eventBus();
        eventBus.<JsonObject>consumer("test",this::handle);
    }

    private void handle(final Message<JsonObject> event) {
        System.out.println("Get: "+event.body());
        sleep();
        System.out.println("Response: ");
        event.reply("Hello");
    }


    private void sleep(){
        System.out.println(Thread.currentThread().getName());
        try {
            Thread.sleep(2000);
        } catch (InterruptedException ex) {
            Logger.getLogger(Receiver.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

我使用群集模式单独运行两个Verticle

这是接收器Verticle的输出:

Response:
Get: {"d":"d"}
vert.x-eventloop-thread-1
Response:
Get: {"d":"d"}
vert.x-eventloop-thread-1
Response:
Get: {"d":"d"}
vert.x-eventloop-thread-1
Response:
Get: {"d":"d"}
vert.x-eventloop-thread-1
Response:
Get: {"d":"d"}
vert.x-eventloop-thread-1
Response:
Get: {"d":"d"}
vert.x-eventloop-thread-1
Response:
Get: {"d":"d"}

但发件人Verticle的输出为空,然后显示错误

 Timed out after waiting 30000(ms) for a reply. address: 26d073b1-e97a-4d9b-88b7-0b9fbe61cb25, repliedAddress: test

我知道它会在30秒内没有结果时发生,但是当我的睡眠时间仅为2秒时,为什么会发生这种情况。

第二个问题,也许我想念官方文档中的内容,但是当所有回调代码都使用事件循环线程时Vertx如何异步,为了避免这种行为我们应该为每个长任务创建工作线程?

提前感谢

1 个答案:

答案 0 :(得分:0)

您在我的电脑上提供的代码示例(java 9 + vertx 3.5.1)。 但是,它有一个问题 - 在Sender Verticle处理程序方法中有以下签名 - handle(AsyncResult<Message<JsonObject>> result)。这意味着它是用于JsonObject的回复实例,但是在Receiver verticle中你回复event.reply("Hello")这是一个简单的刺痛。因此,您将Sender Verticle中的处理程序更新为:

JsonObject body = result.result().body();
System.out.println(body);

会有例外:

java.lang.ClassCastException: java.base/java.lang.String cannot be cast to io.vertx.core.json.JsonObject

因此,如果您使用JsonObject来自Receiver回复,或将Sender中的回复处理程序更改为使用String - 那么它将正常运作。