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...
實現了一個服務提供者, 下面咱們來講明如何消(調)費(用)這個服務.
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()); } }); } }
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>
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...