我有两个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如何异步,为了避免这种行为我们应该为每个长任务创建工作线程?
提前感谢
答案 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
- 那么它将正常运作。