3.2、HTTP服务器Verticle

Verticle类的部分代码和启动方法如下所示:

public class HttpServerVerticle extends AbstractVerticle {
  private static final Logger LOGGER = LoggerFactory.getLogger(HttpServerVerticle.class);
  public static final String CONFIG_HTTP_SERVER_PORT = "http.server.port";  (1)
  public static final String CONFIG_WIKIDB_QUEUE = "wikidb.queue";
  private String wikiDbQueue = "wikidb.queue";

  @Override
  public void start(Future<Void> startFuture) throws Exception {
    wikiDbQueue = config().getString(CONFIG_WIKIDB_QUEUE, "wikidb.queue");  (2)
    HttpServer server = vertx.createHttpServer();
    Router router = Router.router(vertx);
    router.get("/").handler(this::indexHandler);
    router.get("/wiki/:page").handler(this::pageRenderingHandler);
    router.post().handler(BodyHandler.create());
    router.post("/save").handler(this::pageUpdateHandler);
    router.post("/create").handler(this::pageCreateHandler);
    router.post("/delete").handler(this::pageDeletionHandler);

    int portNumber = config().getInteger(CONFIG_HTTP_SERVER_PORT, 8080);  (3)
    server
      .requestHandler(router::accept)
      .listen(portNumber, ar -> {
        if (ar.succeeded()) {
          LOGGER.info("HTTP server running on port " + portNumber);
          startFuture.complete();
        } else {
          LOGGER.error("Could not start a HTTP server", ar.cause());
          startFuture.fail(ar.cause());
        }
      });
  }

// (...)
  1. 我们公开Verticle配置参数中的公共常量:HTTP端口号 以及将消息发送到数据库Verticle的事件总线目的地的名称;
  2. AbstractVerticle#config()方法允许访问已经存在的由Verticle提供的配置。如果没有给出特定值,则第二个参数是默认值;
  3. 配置值不只可以是String对象,也可以是整数,布尔值,复杂的JSON数据等。

该类的其余部分主要是HTTP代码的摘录,以前的数据库代码使用事件总线消息替换。这是indexHandler方法代码:

private final FreeMarkerTemplateEngine templateEngine = FreeMarkerTemplateEngine.create();
  private void indexHandler(RoutingContext context) {
    DeliveryOptions options = new DeliveryOptions().addHeader("action", "all-pages"); (2)
    vertx.eventBus().send(wikiDbQueue, new JsonObject(), options, reply -> {  (1)
      if (reply.succeeded()) {
        JsonObject body = (JsonObject) reply.result().body();   (3)
        context.put("title", "Wiki home");
        context.put("pages", body.getJsonArray("pages").getList());
        templateEngine.render(context, "templates", "/index.ftl", ar -> {
          if (ar.succeeded()) {
            context.response().putHeader("Content-Type", "text/html");
            context.response().end(ar.result());
          } else {
            context.fail(ar.cause());
          }
        });
      } else {
        context.fail(reply.cause());
      }
    });
  }
  1. vertx对象提供对事件总线的访问,我们发送消息到数据库队列 Verticle;
  2. 交付选项允许我们指定标题,有效载荷编解码器和超时时间
  3. 成功后,回复包含有效载荷。

我们可以看到,事件总线消息由一个主体,选项组成,它可以可选地期望一个回复。在没有响应的情况下,发送方法的变体没有处理程序。

我们将有效负载编码为JSON对象,我们通过称为"action"的消息头指定数据库verticle应该执行的操作。

此Verticle的其余代码在路由器处理程序中也使用事件总线来获取和存储数据:

results matching ""

    No results matching ""