下面是垂直线
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();
}
}
下面是主要版本,上面的版本将从该主要版本中部署,并且在对httpserver的任何请求中,都会调用hanlder方法。
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);
}
}
在为任何“ / subscription”请求调用handleSubscription时。客户对象为空。
据我了解,这里创建了两个对象。一个带有start(),另一个不带有start()。
我想一次初始化Redisclient。并在对“ / subscription”的任何请求被调用handleSubscription()时使用此对象。
如何实现?
如何解决此问题。
答案 0 :(得分:0)
请求可能会在客户端初始化实际完成之前进入。
AbstractVerticle
有start()
的两个变体:
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
仅在请求的所有相关资源都已完全初始化时才为其提供服务。