Close client channel

Rahul Patil rpatil at fusionops.com
Thu Aug 20 20:18:29 EDT 2009


Hi Christian,

My apologies for the post.

It was indeed a bug in my code.

I had reconnect logic in the parent class of the business handler in the
channelClosed event.

It has been fixed now.

Thanks for your help.

Regards

Rahul

*From:* Rahul Patil [mailto:rpatil at fusionops.com]
*Sent:* Wednesday, August 19, 2009 11:34 PM
*To:* 'Post 3477137 on Nabble'
*Subject:* RE: Close client channel



Hi Christian,

Thanks for the quick response.

Here is the code fragment I am using.

I have a thread which reads files from a folder and crates a channel to send
it to the server.

The file handler class extends thread and implements ChannelFutureListener.

I am starting the thread from a static block of a separate class.

Please let me know where I am going wrong with this code fragment.

Thanks again.

Regards

Rahul



My SecurePipelineClientFactory is as follows:

      SSLEngine engine = SecureSslContextFactory.*getClientContext*
().createSSLEngine();

      engine.setUseClientMode(*true*);

      pipeline.addLast(RemoteCallConstants.*HANDLER_SSL*,
*new*SslHandler(engine));

            // On top of the SSL handler, add the text line *codec*.

      *pipeline*.addLast(*HANDLER_FRAMER*,
*new*DelimiterBasedFrameDecoder(8192, Delimiters.
*lineDelimiter*()));

      pipeline.addLast(*HANDLER_EXECUTOR*, *new*
ExecutionHandler(*new*OrderedMemoryAwareThreadPoolExecutor(concurrencyLevel,
0,0)));

      pipeline.addLast(*HANDLER_DATA_TRANSFER*, *new* BusinessHandler());



In the MessageReceived method of the above business handler I read a file
from the a file location and then during the last chunk write add the
handler to close the channel.

*public* *void* messageReceived(ChannelHandlerContext ctx, MessageEvent e)

      {

ChannelFuture cf = e.getChannel();

cf.addListener(*new* ChannelFutureListener() {

            *private* *final* ChannelBuffer buffer = ChannelBuffers.*buffer*
(RemoteCallConstants.*CHUNK_SIZE*);

            *private* *long* offset = 0;

            *public* *void* operationComplete(ChannelFuture future)
*throws*Exception

            {

                  *if* (!future.isSuccess())

                  {

                        future.getCause().printStackTrace();

                        future.getChannel().close();

                        bis.close();

                        *return*;

                  }

                  buffer.clear();

                  buffer.writeBytes(bis, (*int*) Math.*min*(fileLength -
offset, buffer.writableBytes()));

                  offset += buffer.writerIndex();

                  ChannelFuture chunkWriteFuture =
future.getChannel().write(buffer);

                  *if* (offset < fileLength)

                  {

                        // Send the next chunk

                        chunkWriteFuture.addListener(*this*);

                  }

                  *else*

                  {

                        // Wrote the last chunk - close the connection if
the write is done.

                        chunkWriteFuture.addListener(*new* FileHandler(em,
bis, startTime));

                  }

            });

}

And here is my implementation of ChannelFutureListener.

FileHandler *extends* Thread *implements* ChannelFutureListener

{

*public* FileHandler(BufferedInputStream fis, *long* startTime)

      {

            *this*.fis = fis;

      }

*public* *void* run()

{

            // Configure the client.

            File file = *new* File(*filepath*);

            ChannelFactory factory =
*new*NioClientSocketChannelFactory(Executors.
*newCachedThreadPool*(), Executors.*newCachedThreadPool*());

            ClientBootstrap bootstrap = *new* ClientBootstrap(factory);

            bootstrap.setOption("tcpNoDelay", *true*);

            bootstrap.setOption("keepAlive", *true*);

            bootstrap.setPipelineFactory(*new* SecurePipelineClientFactory(*
true*));

            *while* (*true*)

            {

*if* (file.exists())

                  {

                        File[] files = file.listFiles();

                        *int* numFiles = files.length;

                        *for* (*int* i = 0; i < numFiles; i++)

                        {

                              // Make a new connection.

                              bootstrap.connect(*new* InetSocketAddress(*
address*, *port*));

                        }

                  }

                  *sleep*(1000 * 20);

            }

}

*public* *void* operationComplete(ChannelFuture future) *throws* Exception

      {

            String dataFile = *filePath*;

            *try*

            {

                  fis.close();

                  File file = *new* File(dataFile);

                  *if* (file.exists())

                  {

                        file.delete();

                  }

            }

            *catch* (IOException e)

            {

                  *log*(e.getMessage(), e);

            }

            *log*("Finished file writing: " + dataFile, *DEBUG*);

            *log*("Time required for file writing : " + (System.*
currentTimeMillis*() - startTime) / 1000 + " sec.", *DEBUG*);

            future.getChannel().disconnect();

            future.getChannel().unbind();

            future.getChannel().close();

      }

}

*From:* christian (via Nabble) [mailto:
ml-user+63078-1538778730 at n2.nabble.com<ml-user%2B63078-1538778730 at n2.nabble.com>]

*Sent:* Wednesday, August 19, 2009 10:57 PM
*To:* Rahul Patil
*Subject:* Re: Close client channel



Hi Rahul,

On Thu, Aug 20, 2009 at 7:43 AM, Rahul Patil<[hidden
email]<http://n2.nabble.com/user/SendEmail.jtp?type=node&node=3477137&i=0>>
wrote:


>
> All,
> I have been working on netty for a while now and really fascinated by its
> flexible and powerful design.
> Currently, I am running into one issue where I need some help.
> I need to open multiple channels on the client, write some data to it and
> then close.
> I am using the same ClientSocketFactory and do bootstrap.connect() every
> time I need a new channel.
> One I am done with the channel I am closing it by channel.close().
> However, when I do netstat I still see the socket with "Established"
status.
> As I keep on creating new channels (by bootstrap.connect()) the
> "Established" socket count keeps piling up.
> How do I close the channel so that it gets removed from the "Established"
> status.


Channel.close() does close the TCP connection - I assume a bug in your
code, if you don't think so, could you assemble a small program which
demonstrates your problem?
Have you checked that you call close on the right channels? Netty
doesn't complain if you call close() on a channel that you already
closed.

hth,
regards,
christian!


> Am I missing out something here?
> Please suggest.
> Thanks
> Rahul

-- 
View this message in context: http://n2.nabble.com/Close-client-channel-tp3477094p3482953.html
Sent from the Netty User Group mailing list archive at Nabble.com.


More information about the netty-users mailing list