代码之家  ›  专栏  ›  技术社区  ›  KRR16

试图从Vertx实例变量的方法访问它时,它为空

  •  0
  • KRR16  · 技术社区  · 8 年前

    下面是垂直

    package com.api.redis.gateway.verticle;
    
    import java.util.UUID;
    
    import io.vertx.core.json.JsonObject;
    import io.vertx.ext.web.RoutingContext;
    import io.vertx.redis.RedisClient;
    import io.vertx.redis.RedisOptions;
    
    public class SimpleRestChild extends SimpleRestServer{
    
         RedisClient client;
    
    
    @Override
    public void start() {
        // TODO Auto-generated method stub
        super.start();
    
        client = RedisClient.create(vertx, new RedisOptions().setHost("127.0.0.1").setPort(6379));
        client.subscribe("channelForServiceToPublish", handler -> {
            if(handler.succeeded())
                System.out.println("SimpleRestServer subscibed to the channel successfully");
        });
    
    }
    
    public void handleSubscription(RoutingContext routingContext) {
        JsonObject requestAsJson = routingContext.getBodyAsJson();
    
        requestAsJson.put("uuid", getUUID());
    
        // this client object is null.
        client.set("request", requestAsJson.toString(), handler ->{
            System.out.println("Simple server is setting value to redis client");
            if(handler.succeeded()) {
                System.out.println("Key and value is stored in Redis Server");
            }else if(handler.failed()) {
                System.out.println("Key and value is failed to be stored on Redis Server with cause : "+ handler.cause().getMessage());
            }
        });
    
    
        client.publish("channelForServerToPublish", "ServiceOne", handler -> {
            if(handler.succeeded()) {
                System.out.println("Simple Server published message successfully");
            }else if(handler.failed()) {
                System.out.println("Simple Server failed to published message");
            }
        });
    
        routingContext.vertx().eventBus().consumer("io.vertx.redis.channelForServiceToPublish", handler -> {
            client.get("response", res ->{
                if(res.succeeded()) {
                    JsonObject responseAsJson = new JsonObject(res.result());
                    if(responseAsJson.getString("uuid").equalsIgnoreCase(requestAsJson.getString("uuid"))) {
                        routingContext.response().setStatusCode(200).end(res.result());
                    }
                }else if(res.failed()) {
                    System.out.println("Failed to get message from Redis Server");
                    routingContext.response().setStatusCode(500).end("Server Error ");
                }
            });
    
    
        });
    }
    
    private String getUUID() {
        UUID uid = UUID.randomUUID();
        return uid.toString();
    }
    

    }

    package com.api.redis.gateway.verticle;
    
    import io.vertx.core.AbstractVerticle;
    import io.vertx.ext.web.Router;
    import io.vertx.ext.web.handler.BodyHandler;
    import io.vertx.redis.RedisClient;
    import io.vertx.redis.RedisOptions;
    
    
    public class SimpleRestServer extends AbstractVerticle{
    
    
    
    @Override
    public void start(){
        int http_port = 9001;
    
        vertx.deployVerticle("com.api.redis.gateway.verticle.SimpleRestChild", handler -> {
            if(handler.succeeded()) {
                System.out.println(" SimpleRestChild deployed successfully");
            }
        });
    
        Router router = Router.router(vertx);
        router.route().handler(BodyHandler.create());
    
        SimpleRestChild child = null;
    
        try {
            child = (SimpleRestChild) Class.forName("com.api.redis.gateway.verticle.SimpleRestChild").newInstance();
        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    
        router.route("/subscription").handler(child::handleSubscription);
        vertx.createHttpServer().requestHandler(router::accept).listen(http_port);
        System.out.println("Server started at port : " + http_port);
    }
    

    }

    当为任何“/订阅”请求调用handleSubscription时。客户端对象为空。

    据我所知,这里正在创造两个物体。一个有start()而另一个没有start()。

    我只想初始化一次Redisclient,并在调用handleSubscription()请求“/subscription”时使用此对象。

    如何做到这一点?

    1 回复  |  直到 8 年前
        1
  •  0
  •   homerman    8 年前

    请求可能在客户端初始化实际完成之前传入。

    AbstractVerticle 有两种变体 start() :

    • 开始() ,和
    • start(Future<Void> startFuture)

    重载版本 Future 参数应用于执行可能长时间运行的初始化,这些初始化在Verticle被认为已部署并准备就绪之前是必需的。(在 docs ).

    因此,您可以尝试如下更改代码:

    public class SimpleRestChild extends SimpleRestServer {
    
        RedisClient client;
    
        @Override
        public void start(Future<Void> startFuture) {
            client = ...
    
            // important point below is that this Verticle's
            // deployment status depends on whether or not
            // the client initialization succeeds
    
            client.subscribe("...", handler -> {
                if(handler.succeeded()) {
                    startFuture.complete();
                } else {
                    startFuture.fail(handler.cause());
                }
            );
        }
    

    }

    public class SimpleRestServer extends AbstractVerticle {
    
    @Override
    public void start(Future<Void> startFuture) {
        int http_port = 9001;
    
        vertx.deployVerticle("...", handler -> {
            // if the child Verticle is successfully deployed
            // then move on to completing this Verticle's
            // initialization
    
            if(handler.succeeded()) {
                Router router = ...
    
                ...
    
                // if the server is successfully installed then
                // invoke the Future to signal this Verticle
                // is deployed
    
                vertx.createHttpServer()
                    .requestHandler(router::accept)
                    .listen(http_port, handler -> {
                        if(handler.succeeded()) {
                            startFuture.complete();
                        } else {
                            startFuture.fail(handler.cause());
                        }
                    });
    
        } else {
            startFuture.fail(handler.cause());
        }
    }
    

    使用这种方法 Verticles 将仅在其所有依赖资源完全初始化时为请求提供服务。