在Netty中重试连接
我正在构建一个客户端套接字系统。要求是: 首先是attemtp连接到远程服务器 当第一次尝试失败时,请继续尝试,直到服务器联机。
我想知道netty中是否有这样的功能可以解决这个问题,或者我最好能解决这个问题。
非常感谢
这是我正在努力的代码片段:
protected void connect() throws Exception {
this.bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool()));
// Configure the event pipeline factory.
bootstrap.setPipelineFactory(new SmpPipelineFactory());
bootstrap.setOption("writeBufferHighWaterMark", 10 * 64 * 1024);
bootstrap.setOption("sendBufferSize", 1048576);
bootstrap.setOption("receiveBufferSize", 1048576);
bootstrap.setOption("tcpNoDelay", true);
bootstrap.setOption("keepAlive", true);
// Make a new connection.
final ChannelFuture connectFuture = bootstrap
.connect(new InetSocketAddress(config.getRemoteAddr(), config
.getRemotePort()));
channel = connectFuture.getChannel();
connectFuture.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future)
throws Exception {
if (connectFuture.isSuccess()) {
// Connection attempt succeeded:
// Begin to accept incoming traffic.
channel.setReadable(true);
} else {
// Close the connection if the connection attempt has
// failed.
channel.close();
logger.info("Unable to Connect to the Remote Socket server");
}
}
});
}
答案 0 :(得分:2)
假设netty 3.x最简单的例子是:
// Configure the client.
ClientBootstrap bootstrap = new ClientBootstrap(
new NioClientSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool()));
ChannelFuture future = null;
while (true)
{
future = bootstrap.connect(new InetSocketAddress("127.0.0.1", 80));
future.awaitUninterruptibly();
if (future.isSuccess())
{
break;
}
}
显然,您希望为设置最大尝试次数的循环设置自己的逻辑,等等.Netty 4.x的引导程序略有不同,但逻辑是相同的。这也是同步,阻止和忽略InterruptedException
;在实际应用程序中,您可以使用ChannelFutureListener
注册Future
,并在Future
完成时收到通知。
在OP编辑问题后添加:
您有ChannelFutureListener
收到通知。如果您想重试连接,则必须让该侦听器持有对引导程序的引用,或者将连接尝试失败的主线程传回给主线程并让它重试该操作。如果您有侦听器(这是最简单的方法),请注意您需要限制重试次数以防止无限递归 - 它是在Netty工作线程的上下文中执行的。如果再次耗尽重试次数,则需要将其重新传达给主线程;你可以通过一个volatile变量来做,或者可以使用观察者模式。
在处理异步时,你必须同时思考。有很多方法可以让那只特别的猫去皮。
答案 1 :(得分:0)
谢谢Brian Roach。连接变量是易失性的,可以在代码之外访问或进一步处理。
final InetSocketAddress sockAddr = new InetSocketAddress(
config.getRemoteAddr(), config.getRemotePort());
final ChannelFuture connectFuture = bootstrap
.connect(sockAddr);
channel = connectFuture.getChannel();
connectFuture.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future)
throws Exception {
if (future.isSuccess()) {
// Connection attempt succeeded:
// Begin to accept incoming traffic.
channel.setReadable(true);
connected = true;
} else {
// Close the connection if the connection attempt has
// failed.
channel.close();
if(!connected){
logger.debug("Attempt to connect within " + ((double)frequency/(double)1000) + " seconds");
try {
Thread.sleep(frequency);
} catch (InterruptedException e) {
logger.error(e.getMessage());
}
bootstrap.connect(sockAddr).addListener(this);
}
}
}
});