From 864de075b216f0e210bc9641e31d4730e7373a11 Mon Sep 17 00:00:00 2001 From: tom916 Date: Mon, 10 Nov 2014 18:12:27 +0800 Subject: [PATCH 1/4] fix not use connectTimeout --- .../java/com/notnoop/apns/internal/ApnsConnectionImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/notnoop/apns/internal/ApnsConnectionImpl.java b/src/main/java/com/notnoop/apns/internal/ApnsConnectionImpl.java index 4f4f85ea..0504760b 100644 --- a/src/main/java/com/notnoop/apns/internal/ApnsConnectionImpl.java +++ b/src/main/java/com/notnoop/apns/internal/ApnsConnectionImpl.java @@ -265,7 +265,8 @@ private synchronized Socket getOrCreateSocket() throws NetworkIOException { if (socket == null || socket.isClosed()) { try { if (proxy == null) { - socket = factory.createSocket(host, port); + socket = factory.createSocket(); + socket.connect(new InetSocketAddress(host, port),connectTimeout); logger.debug("Connected new socket {}", socket); } else if (proxy.type() == Proxy.Type.HTTP) { TlsTunnelBuilder tunnelBuilder = new TlsTunnelBuilder(); From db8e9bf4d10413404c373b62335729fd691bc3c9 Mon Sep 17 00:00:00 2001 From: tom916 Date: Tue, 11 Nov 2014 09:13:42 +0800 Subject: [PATCH 2/4] fix test case --- src/test/java/com/notnoop/apns/internal/MockingUtils.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/java/com/notnoop/apns/internal/MockingUtils.java b/src/test/java/com/notnoop/apns/internal/MockingUtils.java index 032bd91b..96e19a69 100644 --- a/src/test/java/com/notnoop/apns/internal/MockingUtils.java +++ b/src/test/java/com/notnoop/apns/internal/MockingUtils.java @@ -59,6 +59,10 @@ static SocketFactory mockClosedThenOpenSocket(OutputStream out, InputStream in, for (Socket t : socketMocks) stubbing = stubbing.thenReturn(t); + stubbing = when(factory.createSocket()); + for (Socket t : socketMocks) + stubbing = stubbing.thenReturn(t); + return factory; } catch (Exception e) { e.printStackTrace(); From e969a5062090afa0fa67580894c95a28d9fa95b7 Mon Sep 17 00:00:00 2001 From: tom916 Date: Wed, 12 Nov 2014 16:42:25 +0800 Subject: [PATCH 3/4] fix when SocketTimeoutException cause socket close --- .../notnoop/apns/internal/ApnsConnectionImpl.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/notnoop/apns/internal/ApnsConnectionImpl.java b/src/main/java/com/notnoop/apns/internal/ApnsConnectionImpl.java index 0504760b..637c4c92 100644 --- a/src/main/java/com/notnoop/apns/internal/ApnsConnectionImpl.java +++ b/src/main/java/com/notnoop/apns/internal/ApnsConnectionImpl.java @@ -36,6 +36,7 @@ import java.net.InetSocketAddress; import java.net.Proxy; import java.net.Socket; +import java.net.SocketTimeoutException; import java.util.LinkedList; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; @@ -45,6 +46,7 @@ import javax.net.SocketFactory; import javax.net.ssl.SSLSocketFactory; + import com.notnoop.apns.ApnsDelegate; import com.notnoop.apns.ApnsNotification; import com.notnoop.apns.DeliveryError; @@ -52,6 +54,7 @@ import com.notnoop.apns.ReconnectPolicy; import com.notnoop.exceptions.ApnsDeliveryErrorException; import com.notnoop.exceptions.NetworkIOException; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -244,9 +247,15 @@ private boolean readPacket(final InputStream in, final byte[] bytes) throws IOEx } n += count; } catch (IOException ioe) { - if (n == 0) - return false; - throw new IOException("Error after reading "+n+" bytes of packet", ioe); + if (!(ioe instanceof SocketTimeoutException)) { + if (n == 0) + return false; + throw new IOException("Error after reading "+n+" bytes of packet", ioe); + } else { + if (logger.isDebugEnabled()) { + logger.debug("just SocketTimeoutException ignore"); + } + } } } return true; From 58946b6e87021b29c77dab5cd76cee6b7343d4e5 Mon Sep 17 00:00:00 2001 From: tom916 Date: Tue, 18 Nov 2014 09:31:54 +0800 Subject: [PATCH 4/4] fix sendMessage not catch NetworkIOException --- .../apns/internal/ApnsConnectionImpl.java | 39 +++++++++++-------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/notnoop/apns/internal/ApnsConnectionImpl.java b/src/main/java/com/notnoop/apns/internal/ApnsConnectionImpl.java index 637c4c92..8e15343e 100644 --- a/src/main/java/com/notnoop/apns/internal/ApnsConnectionImpl.java +++ b/src/main/java/com/notnoop/apns/internal/ApnsConnectionImpl.java @@ -139,7 +139,6 @@ private void monitorSocket(final Socket socket) { Thread t = threadFactory.newThread(new Runnable() { final static int EXPECTED_SIZE = 6; - @SuppressWarnings("InfiniteLoopStatement") @Override public void run() { logger.debug("Started monitoring thread"); @@ -340,26 +339,32 @@ private synchronized void sendMessage(ApnsNotification m, boolean fromBuffer) th attempts = 0; break; } catch (IOException e) { - Utilities.close(socket); - if (attempts >= RETRIES) { - logger.error("Couldn't send message after " + RETRIES + " retries." + m, e); - delegate.messageSendFailed(m, e); - Utilities.wrapAndThrowAsRuntimeException(e); - } - // The first failure might be due to closed connection (which in turn might be caused by - // a message containing a bad token), so don't delay for the first retry. - // - // Additionally we don't want to spam the log file in this case, only after the second retry - // which uses the delay. - - if (attempts != 1) { - logger.info("Failed to send message " + m + "... trying again after delay", e); - Utilities.sleep(DELAY_IN_MS); - } + dealException(attempts, m, e); + } catch (NetworkIOException e){ + dealException(attempts, m, e); } } } + private void dealException(int attempts,ApnsNotification m,Exception e){ + Utilities.close(socket); + if (attempts >= RETRIES) { + logger.error("Couldn't send message after " + RETRIES + " retries." + m, e); + delegate.messageSendFailed(m, e); + Utilities.wrapAndThrowAsRuntimeException(e); + } + // The first failure might be due to closed connection (which in turn might be caused by + // a message containing a bad token), so don't delay for the first retry. + // + // Additionally we don't want to spam the log file in this case, only after the second retry + // which uses the delay. + + if (attempts != 1) { + logger.info("Failed to send message " + m + "... trying again after delay", e); + Utilities.sleep(DELAY_IN_MS); + } + } + private synchronized void drainBuffer() { logger.debug("draining buffer"); while (!notificationsBuffer.isEmpty()) {