Verticle in Vert.x

来源:互联网 发布:手机sdr软件 编辑:程序博客网 时间:2024/05/24 05:04

上节讲了,Verticle实例有start()和stop()方法,你可以在这两个方法中实现具体工作然后将实例注册到Vertx实例中将自动调用这两个方法。verticle有些类似Servlet或者JavaEE中事件驱动的EJB,但是要实现并发处理,verticle的工作模式与前两者并不同。本节将介绍如何注册verticle到vertx以及verticle内部之间如何通过eventbus互相通信。

创建Verticle

首先创建一个继承自io.vertx.core.AbstractVerticle的类:

import io.vertx.core.AbstractVerticle;public class BasicVerticle extends AbstractVerticle {}

你已经创建了一个BasicVerticle类,但是它还不包含任何方法,下面添加start()和stop()方法。

start()

AbstractVerticle类包含了start()方法,你可以override它并在里面添加你想让它去做的工作,如:

public class BasicVerticle extends AbstractVerticle {    @Override    public void start() throws Exception {        System.out.println("BasicVerticle started");    }}

这里只是打印了一串字符。原则上start()里面可以做任何它应当做的事情,比如initialize当前verticle、创建一个HTTP或TCP Server、给EventBus注册Event Handlers、或者注册其它Verticle实例到Vertx实例等。
start()方法还有另外一个用法,那就是传递一个Future对象的参数,如:

public class BasicVerticle extends AbstractVerticle {    @Override    public void start(Future future) throws Exception {        System.out.println("BasicVerticle started");    }}

Future对象参数可以用来异步的告诉Vertx实例是否此次注册verticle成功了。

stop()

stop()方法在vertx实例停止的时候或者当verticle被从vertx实例卸载的时候。下面是在自己类中对它的覆盖:

public class BasicVerticle extends AbstractVerticle {    @Override    public void start() throws Exception {        System.out.println("BasicVerticle started");    }    @Override    public void stop() throws Exception {        System.out.println("BasicVerticle stopped");    }}

Deploy Verticle

创建完成自己的Verticle类BasicVerticle之后,就可以注册它到Vert.x实例中了:

public class VertxVerticleMain {    public static void main(String[] args) throws InterruptedException {        Vertx vertx = Vertx.vertx();        vertx.deployVerticle(new BasicVerticle());    }}

需要注意两点:第一,当vertx.deployVerticle(new BasicVerticle());执行时,Verticle的start()方法将会被调用;第二,vertx.deployVerticle()方法是异步将Verticle实例配置(注册),所以当该方法返回时,可能并没有注册完成,要想确切的知道何时被成功注册了,你可以通过提供一个Handler完成,如:

vertx.deployVerticle(new BasicVerticle(), new Handler<AsyncResult<String>>() {    @Override    public void handle(AsyncResult<String> stringAsyncResult) {        System.out.println("BasicVerticle deployment complete");        }    });

或者使用Java中的lambda表达式:

vertx.deployVerticle(new BasicVerticle(), stringAsyncResult -> {        System.out.println("BasicVerticle deployment complete");});

从别的Verticle中注册其它的Verticle

可以在一个verticle内部注册其它的verticle,比如:

public class BasicVerticle extends AbstractVerticle {    @Override    public void start() throws Exception {        System.out.println("BasicVerticle started");        vertx.deployVerticle(new SecondVerticle());    }    @Override    public void stop() throws Exception {        System.out.println("BasicVerticle stopped");    }}

请读者自行体会这样做会带来程序业务逻辑上的层次流程关系。

使用Event Bus

verticle可以监听到来自Event bus的消息,也可以给Event bus写消息。

监听消息

verticle监听来自Event bus的消息,是通过一个自定义的“Address”实现的,该“Address”是可以随意定义的一个字符串名称。
多个verticles可以监听同一个“Address”的消息,也可以给同一个“Address”发送消息。

public class MyVerticle extends AbstractVerticle {    public void start(Future<Void> startFuture) {        vertx.eventBus().consumer("anAddress", message -> {            System.out.println("1 received message.body() = "                + message.body());        });    }}

我们在start()中让MyVerticle监听来自Event Bus的anAddress地址的消息。

发送消息

给Event bus发送消息可以通过send()或publish()完成。
publish()方法发送的消息会被监听在该地址的所有verticle接收,注意是所有。
send()方法发送的消息只会被监听在该地址的其中一个verticle接收,到底哪个接收由vertx决定,vertx怎么决定的呢?官方解释是通过“non-strict round robin”原则,简单理解就是按照不严格的规则随机的选择一个verticle收到该消息。请读者自己琢磨send()这种方式的好处。

Vertx vertx = Vertx.vertx();vertx.deployVerticle(new EventBusReceiverVerticle("R1"));vertx.deployVerticle(new EventBusReceiverVerticle("R2"));Thread.sleep(3000);vertx.deployVerticle(new EventBusSenderVerticle());
public class EventBusSenderVerticle extends AbstractVerticle {    public void start(Future<Void> startFuture) {        vertx.eventBus().publish("anAddress", "message 2");        vertx.eventBus().send   ("anAddress", "message 1");    }}
public class EventBusReceiverVerticle extends AbstractVerticle {    private String name = null;    public EventBusReceiverVerticle(String name) {        this.name = name;    }    public void start(Future<Void> startFuture) {        vertx.eventBus().consumer("anAddress", message -> {            System.out.println(this.name +                 " received message: " +                message.body());        });    }}

运行以上代码,你将会看到message 2会被两个verticle接收到,而message 1只会被其中一个接收。

2 0
原创粉丝点击