Vert.x 3: 服務代理

Vert.x 3: SockJS 服務代理
Vert.x 3: 服務代理
Vert.x 3: Node和瀏覽器端事件總線重連html

服務代理提供了在事件總線上暴露服務, 而且減小調用服務所要求的代碼的一種方式. 服務代理幫助你解析事件總線的消息結構和接口方法的映射關係, 好比方法名稱, 參數等等. 本質上是一種RPC. 它經過代碼生成的方式建立服務代理.java

所以須要實現兩個Verticle, 一個爲 QrcodeService, 提供二維碼生成服務. 另外一個 Verticle 用於服務註冊.git

Verticle 運行在一個兩節點的集羣環境中中github

提供服務

要提供一個服務, 須要一個服務接口, 一個實現和一個Verticlenpm

  • 服務接口: QrcodeService, 服務接口, 定義了二維碼生成和代理建立接口.編程

  • 服務實現: QrcodeServiceImpl, 服務實現類, 實際的二維碼生成函數在這裏實現json

  • 服務註冊: QrcodeServiceVerticle, 用於註冊服務segmentfault

服務接口是經過 @ProxyGen 標註的接口, 例如:瀏覽器

package com.totorotec.service.qrcode;

import io.vertx.codegen.annotations.ProxyGen;
import io.vertx.codegen.annotations.VertxGen;
import io.vertx.core.AsyncResult;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonObject;

import com.totorotec.service.qrcode.impl.QrcodeServiceImpl;

@ProxyGen
@VertxGen
public interface QrcodeService {
  public static final String SERVICE_ADDRESS = "com.totorotec.servicefactory.qrcode-service";

  static QrcodeService create(Vertx vertx, JsonObject config) {
    return new QrcodeServiceImpl(vertx, config);
  }

  static QrcodeService createProxy(Vertx vertx, String address) {
    return new QrcodeServiceVertxEBProxy(vertx, address);
  }

  void getQrcode(String text, int imageSize, String imageType, String outputType, String filePatten, Handler<AsyncResult<JsonObject>> resultHandler);
}

注意: java.lang.IllegalStateException: Cannot find proxyClass, 把`插件的版本升級到3.7.0`maven

<plugin>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.7.0</version>
  <configuration>
    <source>1.8</source>
    <target>1.8</target>
  </configuration>
</plugin>

另外: 須要給插件 maven-compiler-plugin 增長符號處理器配置 annotationProcessor, 以下

<plugin>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.7.0</version>
  <configuration>
    <source>1.8</source>
    <target>1.8</target>
    <annotationProcessors>
      <annotationProcessor>io.vertx.codegen.CodeGenProcessor</annotationProcessor>
    </annotationProcessors>
  </configuration>
</plugin>

完整的 pom.xml 項目文件能夠參考: https://github.com/developerw...

消費服務

實現了一個服務提供者, 下面咱們來講明如何消(調)費(用)這個服務.

在Vertx JVM中從Java端調用

package com.totorotec.service.qrcode;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.logging.Logger;
import io.vertx.core.logging.LoggerFactory;

/**
 * QrcodeServiceConsumer
 */
public class QrcodeServiceConsumer extends AbstractVerticle {

  private static final Logger logger = LoggerFactory.getLogger(QrcodeServiceConsumer.class);

  @Override
  public void start() throws Exception {
    super.start();

    QrcodeService qrcodeServiceProxy = QrcodeService.createProxy(vertx, QrcodeService.SERVICE_ADDRESS);
    qrcodeServiceProxy.getQrcode("https://www.qq.com", 600, "jpg", "file",
        "/tmp/%s.%s", ar -> {
          if (ar.succeeded()) {
            logger.info(ar.result().encodePrettily());
          } else {
            logger.error(ar.cause());
          }
        });
  }
}

在Vertx JVM中從Javascript調用

var service = require("qrcode-service-js/qrcode_service");

console.log("Creating service proxy...");
var proxy = service.createProxy(vertx, "com.totorotec.servicefactory.qrcode-service");

proxy.getQrcode("https://www.qq.com", 380, "png", "dataurl", "/tmp/%s.%s", function (error, data) {
  if(error == null) {
    console.log(data);
  }
  else {
    console.log(error);
  }
});

在瀏覽器中調用

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Test Qrcode Service in Browser</title>
  <script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>
  <script src="./vertx-eventbus.js"></script>
  <script src="./qrcode_service-proxy.js"></script>
</head>

<body>

  <div id="qrcode"></div>

  <script>

    var qrcodeStr;
    var eb = new EventBus('http://localhost:8080/eventbus');
    eb.onopen = function () {
      var service = new QrcodeService(eb, "com.totorotec.servicefactory.qrcode-service");
      service.getQrcode("https://www.qq.com", 380, "png", "dataurl", "/tmp/%s.%s", function (error, data) {
        if (error == null) {
          console.log(data.data);
          qrcodeStr = data.data
          document.getElementById("qrcode").innerHTML = qrcodeStr;

        }
        else {
          console.log(error);
        }
      });
    };
  </script>

</body>

</html>

在Node.js環境中調用

var EventBus = require("vertx3-eventbus-client");

var eb = new EventBus("http://localhost:8080/eventbus");

eb.onopen = function () {
  // 導入代理模塊
  var QrcodeService = require("../target/classes/qrcode-service-js/qrcode_service-proxy");
  // 實例化服務對象
  var service = new QrcodeService(eb, "com.totorotec.servicefactory.qrcode-service");
  // 調用服務
  service.getQrcode("https://www.qq.com", 380, "png", "dataurl", "/tmp/%s.%s", function (data, error) {
    if(error == null) {
      console.log(data);
    } else {
      console.log(error);
    }
  });
}

結語

事件總線, 對於異構系統集成來說是一個很好的工具. 經過定義服務接口, 服務實現, 代理類代碼生成, 服務註冊, 事件總線橋, 咱們能夠把異構系統的各個端點鏈接到事件總線中, 實現分佈式的, 異構系統的通訊, 事件處理.

異構還特別對團隊有用, 大的團隊使用不一樣的開發工具, 語言, 運行時系統等, 均可以很方便的進行集成, 只要你在JVM的生態裏面, 無論你使用JVM的什麼語言. 即便你不在JVM生態裏面, 例如Node.js, 瀏覽器, 其餘編程語言等, Vert.x還提供了一個TCP事件總線橋的方式進行集成.

咱們前面只介紹了SockJS這種集成方式, 當前互聯網應用程序大部分使用HTTP做爲應用層協議, 原生TCP的方式用的比較少, 在這裏就不詳細說明了, 有須要的能夠參考Vertx的文檔: http://vertx.io/docs/vertx-tc...

項目源碼

完整的項目和實現能夠參考個人倉庫: https://github.com/developerw...

相關文章
相關標籤/搜索