AndroidAsync TCP -- proper way to detect socket is no longer available using write?

246 views Asked by At

I am wondering what is the proper way to check on the client side that a TCP socket opened using the AndroidAsync library is no longer available? This is in the case the (plain TCP, non-AndroidAsync) server did not initiate explicitly closing the socket (so the ClosedCallback is not invoked). For instance, when the server has been cold rebooted.

It seems that the DataCallback is available only when the server sends back data and can't be used to receive error messages.

It seems to me also that

Util.writeAll(socket, (byte[]) payload.array(), new CompletedCallback()
    {
        @Override
        public void onCompleted(Exception ex)
        {
            if (ex != null)
            {
                Log.e(TAG, "write failed with ex message= " + ex.getMessage());
                throw new RuntimeException(ex);
            }
        }
    });

does not throw an Exception either.

So at this point I'm not sure how to detect the socket is no longer available even if the client periodically writes data to it.

3

There are 3 answers

3
behelit On

You could use the closed/end callbacks

socket.setClosedCallback(new CompletedCallback()
{
            @Override
            public void onCompleted(Exception ex)
            {

            }
        });

socket.setEndCallback(new CompletedCallback()
{
            @Override
            public void onCompleted(Exception ex)
            {

            }
 });
1
user207421 On

It will throw an IOexception if you send enough data or call it enough times. It won't throw on the first call due to TCP buffering at both ends.

0
Objectist On

I ended up implementing some sort of a "ping"-alike periodic check. The client opens and immediately closes a TCP connection to the very same port using a plain Java NIO socket call (not using AndroidAsync). If that one times out, it is assumed that the connection has been lost, and a recovery attempt is made once it succeeds again. This periodic check is performed only when the app has focus, or is just awakened. This is clearly a far from ideal workaround but it seems to work for my purposes.