这是一个关于 vertx web server 的简单 demo. 我设置了两个 handler, 一个用于打印一行文字, 另一个用来做一个反向代理,将请求转发到 baidu.com.
第一个代码块是一个正确的写法,但我在这个需求上,想要把第二个 handler 用代理的形式放到第一个 handler 里面,即合二为一. 这个处理我写在第二个代码块里, 但我有一些疑问, 请您帮我解答一下疑惑?
我有三个问题, 并且将这些问题放在了代码注释里,以 Issue 开头标注.
原始代码块
public class VertxRouteDemo {
public static void main(String[] args) {
Vertx vertx = Vertx.vertx();
HttpServer server = vertx.createHttpServer();
Router router = Router.router(vertx);
router.route()
// 第一个 handler
.handler(event -> {
System.out.println("Just print to confirm executed");
event.next();
});
HttpClient httpClient = vertx.createHttpClient();
HttpProxy proxy = HttpProxy.reverseProxy( httpClient).origin(80, "baidu.com");
// 第二个 handler
router.route().handler(proxy);
server.requestHandler(router);
server.listen(18081);
}
}
修改后的代码块
public class VertxRouteDemo {
public static void main(String[] args) {
Vertx vertx = Vertx.vertx();
HttpServer server = vertx.createHttpServer();
Router router = Router.router(vertx);
router.route()
.handler(event -> {
System.out.println("Just print to confirm executed");
// 把它挪到这里,相当于对第二个 handler 做了代理,打印一行信息确认是否执行
HttpClient httpClient = vertx.createHttpClient();
HttpProxy proxy = HttpProxy.reverseProxy( httpClient).origin(80, "baidu.com");
// Issue 1: 这里是否会导致阻塞?
// 我猜测大概是不会导致阻塞的,即非阻塞,就是说这个方法立即返回。
// 在非阻塞的前提下引出第二个问题,我希望这个方法执行完成后再去调用下面的 next(),这段代码逻辑是不是有问题?
// 因为这个方法立即返回,那就会立即去执行下面的 next()方法了
// Issue 2: 如果这里是非阻塞方法,那我应该怎么改才能达到目的
proxy.handle(event);
event.next();
});
server.requestHandler(router);
server.listen(18081);
}
}
第二个修改后的代码块
public class VertxRouteDemo {
public static void main(String[] args) {
Vertx vertx = Vertx.vertx();
HttpServer server = vertx.createHttpServer();
Router router = Router.router(vertx);
router.route()
.handler(event -> {
System.out.println("Just print to confirm executed");
// 把它挪到这里,相当于对第二个 handler 做了代理,打印一行信息确认是否执行
HttpClient httpClient = vertx.createHttpClient();
HttpProxy proxy = HttpProxy.reverseProxy( httpClient).origin(80, "baidu.com");
// 假设 handle(event)是阻塞的,所以使用了这种方法去使它不阻塞 eventloop 线程
// Issue 3: 这是写是对的吗?
vertx.executeBlocking(promise -> {
proxyHandler.handle(event);
promise.complete();
}, result -> {
if (result.succeeded()) {
// 阻塞操作完成后异步调用 event.next()
event.next();
} else {
// 处理阻塞操作失败的情况
event.fail(result.cause());
}
});
event.next();
});
server.requestHandler(router);
server.listen(18081);
}
}
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.