Reconnect to server java

ochinchina / NettyConnection.java

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

package com . nokia . nls . nmif ;
import io . netty . bootstrap . Bootstrap ;
import io . netty . buffer . ByteBuf ;
import io . netty . channel . Channel ;
import io . netty . channel . ChannelFuture ;
import io . netty . channel . ChannelFutureListener ;
import io . netty . channel . ChannelHandler ;
import io . netty . channel . ChannelHandlerContext ;
import io . netty . channel . ChannelInboundHandlerAdapter ;
import io . netty . channel . ChannelInitializer ;
import io . netty . channel . ChannelOption ;
import io . netty . channel . nio . NioEventLoopGroup ;
import io . netty . channel . socket . SocketChannel ;
import io . netty . channel . socket . nio . NioSocketChannel ;
import java . io . IOException ;
import java . net . InetSocketAddress ;
import java . net . SocketAddress ;
import java . util . Timer ;
import java . util . TimerTask ;
public class NettyConnection
private Bootstrap bootstrap = new Bootstrap ();
private SocketAddress addr_ ;
private Channel channel_ ;
private Timer timer_ ;
public NettyConnection ( String host , int port , Timer timer )
this ( new InetSocketAddress ( host , port ), timer );
>
public NettyConnection ( SocketAddress addr , Timer timer )
this . addr_ = addr ;
this . timer_ = timer ;
bootstrap . group ( new NioEventLoopGroup () );
bootstrap . channel ( NioSocketChannel . class );
bootstrap . option ( ChannelOption . SO_KEEPALIVE , true );
bootstrap . handler ( new ChannelInitializer < SocketChannel >()
@ Override
public void initChannel ( SocketChannel ch ) throws Exception
ch . pipeline (). addLast ( createNMMessageHandler () );
>
>);
scheduleConnect ( 10 );
>
public void send ( String msg ) throws IOException
if ( channel_ != null && channel_ . isActive () )
ByteBuf buf = channel_ . alloc (). buffer (). writeBytes ( msg . getBytes () );
channel_ . writeAndFlush ( buf );
> else
throw new IOException ( «Can’t send message to inactive connection» );
>
>
public void close ()
try
channel_ . close (). sync ();
> catch ( InterruptedException e )
e . printStackTrace ();
>
>
private void doConnect ()
try
ChannelFuture f = bootstrap . connect ( addr_ );
f . addListener ( new ChannelFutureListener ()
@ Override public void operationComplete ( ChannelFuture future ) throws Exception
if ( ! future . isSuccess () ) < //if is not successful, reconnect
future . channel (). close ();
bootstrap . connect ( addr_ ). addListener ( this );
> else < //good, the connection is ok
channel_ = future . channel ();
//add a listener to detect the connection lost
addCloseDetectListener ( channel_ );
connectionEstablished ();
>
>
private void addCloseDetectListener ( Channel channel )
//if the channel connection is lost, the ChannelFutureListener.operationComplete() will be called
channel . closeFuture (). addListener ( new ChannelFutureListener ()
@ Override
public void operationComplete ( ChannelFuture future )
throws Exception
connectionLost ();
scheduleConnect ( 5 );
>
>);
>
>);
> catch ( Exception ex )
scheduleConnect ( 1000 );
>
>
private void scheduleConnect ( long millis )
timer_ . schedule ( new TimerTask ()
@ Override
public void run ()
doConnect ();
>
>, millis );
>
private ChannelHandler createNMMessageHandler ()
return new ChannelInboundHandlerAdapter ()
@ Override
public void channelRead ( ChannelHandlerContext ctx , Object msg )
ByteBuf buf = ( ByteBuf ) msg ;
int n = buf . readableBytes ();
if ( n > 0 )
byte [] b = new byte [ n ];
buf . readBytes ( b );
handleMessage ( new String ( b ) );
>
>
>;
>
public void handleMessage ( String msg )
System . out . println ( msg );
>
public void connectionLost ()
System . out . println ( «connectionLost()» );
>
public void connectionEstablished ()
try
send ( «hello» );
> catch ( IOException e )
e . printStackTrace ();
>
>
public static void main ( String . args )
NettyConnection conn = new NettyConnection ( «127.0.0.1» , 34567 , new Timer () );
for ( ; ; )
try < Thread . sleep ( 100 ); >catch ( Exception ex ) <>
>
>
>

Источник

Reconnect a Java socket connection on disconnect

If the device reboots without properly closing the socket, I don’t know of anything that will allow you to detect it. Your server will not be able to detect that the socket has gone away, in this case, unless the device comes back up or until the TCP/IP stack on your server gives up and declares the connection is dead. At some point you’ll get an IOException. You need to catch that Exception and then reconnect when it occurs.

You’re really at the mercy of the behavior of TCP/IP here. When one end of a connection simply disappears (no FIN packet), the other end may wait an arbitrary length of time (depending on many factors) before deciding the connection is dead.

If you want to catch this problem earlier — and you can guarantee that the device will respond within a set amount of time, then set a timeout on the socket. If you do this, you’ll get a SocketTimeoutException if the device doesn’t respond, and you can then close the socket and try reopening the socket. I have used this with success.

Solution 2

If your software is just waiting for data from the home automation device the only way to detect that the device is gone is to enable the SO_KEEPALIVE option in the socket open to communicate with the device.

To do this just call setKeepAlive(true) method on the socket and that will make the underlying socket implementation enable the SO_KEEP_ALIVE option.

This will make the underlying implementation periodically exchange some data with the remote endpoint and if the device dies while you are waiting for data, an exception will be thrown.

The only problem is that this keep alive time-out depends on the operating system and sometimes cannot be changed.

If you need shorter timeouts, there’s no other way than implementing a periodic probe on the device.

Solution 3

I have solved this exact same problem.

If you want to catch this problem earlier — and you can guarantee that the device will respond within a set amount of time, then set a timeout on the socket. If you do this, you’ll get a SocketTimeoutException if the device doesn’t respond, and you can then close the socket and try reopening the socket. I have used this with success.

I get it to close the socket then attempt to reopen it, which it runs that code fine. The only problem is that once I close a socket I cannot reopen it, I get the exception that the socket is closed. This happens every time. How do I close a socket then reopen it with out getting this exception?

Источник

Java – Auto-reconnect to a server using a socket in Java

There is a component in my application that listens to a server via TCP (so it only receives data, the output-stream is never used). The only reason for a potential disconnect are technical issues. From a logical point of view, the connection should stay open forever.

I know that I have to implement some kind of ping/pong strategy if I want to detect a connection failure immediately. But in my case, it is not necessary to detect a dropped connection immediately as long as it gets detected at all (let’s say some minutes or hours later).

  1. If I don’t use some kind of pingpong/alive-check strategy and the connection drops, will I get an IOException in my application logic some time later (it would be okay if it took some hours) or is it possible that the dropped connection isn’t detected at all?
  2. Would the code below fit my requirements? It’s a bit ugly (many try-catch/while(true) and even sleep, but I’m wondering if a timed out connection could be recognized after a certain amount of time (e.g. due to an IOException in the blocking BufferedReader.readLine method).
  3. Apart from the questions above, what could I do better?
public class Receiver implements Runnable < private Socket socket; private final String host; private final int port; private final int connectionRetryAfter = 10* 1000; public Receiver(String host, int port) < // assignments. >@Override public void run() < tryCreateSocket(); listenToServer(); >private void listenToServer() < String receivedLine; BufferedReader buf; while(true) < try < buf = new BufferedReader(new InputStreamReader(socket.getInputStream())); while ((receivedLine = buf.readLine()) != null) < // do something with 'inputLine' >> catch (IOException e) < // logging >finally < closeSocket(); >// At this point, either an exception occured or the stream equals null (which means it's closed?) tryCreateSocket(); > > private void tryCreateSocket() < try < socket = new Socket(host, port); >catch (IOException e) < // logging try < Thread.sleep(connectionRetryAfter); >catch(InterruptedException ex) < // logging Thread.currentThread().interrupt(); >// retry tryCreateSocket(); > > private void closeSocket() < if (socket != null) < try < socket.close(); >catch (IOException e) < // logging >> > 

Best Solution

listenToServer() should certainly throw an IOException if the connection/reconnection attempt fails. Consider the case when the server is down. Do you really want to loop inside this method forever?

Источник

Client Failed to connect, how do I attempt a reconnect?

send pies

posted 15 years ago

  • Report post to moderator
  • I am very new to java and I am creating a portable network class. Everything works fine except one thing, if the client fails to connect to the server, say it is not up yet, how do I attempt another connection with a socket?
    do
    if say socket = new socket(IP, Port);
    loop until timeout retries reached or connected

    send pies

    posted 15 years ago

  • Report post to moderator
  • I haven’t fully read your code, but if you want to reconnect to a host, you can do something like this:

    One more thing, if the socket fails to connect, the socket object will be null. So when you check whether the socket is connected or not (socket.isConnected()), it will throw a NullPointerException.

    SCJP 5.0, SCWCD 1.4, SCBCD 1.3, SCDJWS 1.4
    My Blog

    send pies

    posted 15 years ago

  • Report post to moderator
  • No that does not help but thank you for helping. The problem is that when I try to reuse the socket over and over again it just skips over it after the first failed attempt. I would like to be able to attempt reconnects without having to restart the application.

    send pies

    posted 15 years ago

  • Report post to moderator
  • Ok I see what was wrong now. It would appear that the socket was just initializing the first time and took a few seconds to start and if it failed to connect, the next time you tried to reconnect it would only look for > a second before moving on so a while loop was necessary. Thank you for your help and I will be back I am sure once I start getting into the hard parts.

    Источник

    Читайте также:  File get contents php context
    Оцените статью