gpt4 book ai didi

tcp - Netty:在多个 Netty 客户端之间共享 NioClientSocketChannelFactory 的正确方法是什么

转载 作者:可可西里 更新时间:2023-11-01 02:54:43 26 4
gpt4 key购买 nike

我是 Netty 的新手。我正在使用“Netty 3.6.2.Final”。我创建了一个 Netty 客户端 (MyClient),它与远程服务器通信(该服务器实现了基于 TCP 的自定义协议(protocol))。我为每个 MyClient 实例(在构造函数中)创建一个新的 ClientBootstrap 实例。我的问题是,如果我在 MyClient 的所有实例之间共享“NioClientSocketChannelFactory”工厂对象,那么我何时/如何释放与“NioClientSocketChannelFactory”关联的所有资源?

换句话说,由于我的 Netty 客户端运行在一个 24x7 全天候运行的 JBOSS 容器中,我是否应该通过调用“bootstrap.releaseExternalResources();”来释放所有资源?我应该何时/何地这样做?

更多信息:我的 Netty 客户端是从 JBOSS 容器内的两个场景调用的。首先,在无限循环中,每次传递需要发送到远程服务器的字符串(效果类似于下面的代码)

for( ; ; ){
//Prepare the stringToSend
//Send a string and receive a string
String returnedString=new MyClient().handle(stringToSend);
}

另一种情况是我的 Netty Client 在并发线程中调用,每个线程调用“new MyClient().handle(stringToSend);”。

我在下面给出了框架代码。它与 Netty 网站上的 TelnetClient 示例非常相似。

我的客户

import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
public class MyClient {
//Instantiate this only once per application
private final static Timer timer = new HashedWheelTimer();

//All below must come from configuration
private final String host ="127.0.0.1";
private final int port =9699;
private final InetSocketAddress address = new InetSocketAddress(host, port);
private ClientBootstrap bootstrap;

//Timeout when the server sends nothing for n seconds.
static final int READ_TIMEOUT = 5;

public MyClient(){
bootstrap = new ClientBootstrap(NioClientSocketFactorySingleton.getInstance());
}

public String handle(String messageToSend){
bootstrap.setOption("connectTimeoutMillis", 20000);
bootstrap.setOption("tcpNoDelay", true);
bootstrap.setOption("keepAlive", true);
bootstrap.setOption("remoteAddress", address);
bootstrap.setPipelineFactory(new MyClientPipelineFactory(messageToSend,bootstrap,timer));

// Start the connection attempt.
ChannelFuture future = bootstrap.connect();

// Wait until the connection attempt succeeds or fails.
channel = future.awaitUninterruptibly().getChannel();


if (!future.isSuccess()) {
return null;
}

// Wait until the connection is closed or the connection attempt fails.
channel.getCloseFuture().awaitUninterruptibly();

MyClientHandler myClientHandler=(MyClientHandler)channel.getPipeline().getLast();
String messageReceived=myClientHandler.getMessageReceived();
return messageReceived;
}
}

单例 NioClientSocketChannelFactory

public class NioClientSocketFactorySingleton {
private static NioClientSocketChannelFactory nioClientSocketChannelFactory;

private NioClientSocketFactorySingleton() {
}

public static synchronized NioClientSocketChannelFactory getInstance() {
if ( nioClientSocketChannelFactory == null) {
nioClientSocketChannelFactory=new NioClientSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool());
}
return nioClientSocketChannelFactory;
}

protected void finalize() throws Throwable {
try{
if(nioClientSocketChannelFactory!=null){
// Shut down thread pools to exit.
nioClientSocketChannelFactory.releaseExternalResources();
}
}catch(Exception e){
//Can't do anything much
}
}
}

我的客户管道工厂

public class MyClientPipelineFactory implements ChannelPipelineFactory {

private String messageToSend;
private ClientBootstrap bootstrap;
private Timer timer;
public MyClientPipelineFactory(){

}
public MyClientPipelineFactory(String messageToSend){
this.messageToSend=messageToSend;
}

public MyClientPipelineFactory(String messageToSend,ClientBootstrap bootstrap, Timer timer){
this.messageToSend=messageToSend;
this.bootstrap=bootstrap;
this.timer=timer;
}

public ChannelPipeline getPipeline() throws Exception {

// Create a default pipeline implementation.
ChannelPipeline pipeline = pipeline();

// Add the text line codec combination first,
//pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
pipeline.addLast("decoder", new StringDecoder());
pipeline.addLast("encoder", new StringEncoder());

//Add readtimeout
pipeline.addLast("timeout", new ReadTimeoutHandler(timer, MyClient.READ_TIMEOUT));

// and then business logic.
pipeline.addLast("handler", new MyClientHandler(messageToSend,bootstrap));


return pipeline;
}
}

我的客户端处理程序

public class MyClientHandler extends SimpleChannelUpstreamHandler { 

private String messageToSend="";
private String messageReceived="";


public MyClientHandler(String messageToSend,ClientBootstrap bootstrap) {
this.messageToSend=messageToSend;
this.bootstrap=bootstrap;
}

@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e){
e.getChannel().write(messageToSend);
}

@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e){
messageReceived=e.getMessage().toString();
//This take the control back to the MyClient
e.getChannel().close();
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
// Close the connection when an exception is raised.
e.getChannel().close();

}


}

最佳答案

只有在确定不再需要 releaseExternalResources() 时才应调用它。例如,当应用程序停止或取消部署时。

关于tcp - Netty:在多个 Netty 客户端之间共享 NioClientSocketChannelFactory 的正确方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17933798/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com