private void closeSocket(Socket socket) { try { if (socket != null) { socket.close(); } } catch (Exception e) { logger.error(e.getMessage(), e); } }
@Override public void sendNotification(PushNotification notification) { byte[] plBytes = null; String payload = notification.getPayload().toString(); try { plBytes = payload.getBytes(CHARSET_ENCODING); if (plBytes.length > PAY_LOAD_MAX_LENGTH) { logger.error("Payload execeed limit, the maximum size allowed is 256 bytes. " + payload); return; } } catch (UnsupportedEncodingException e) { logger.error(e.getMessage(), e); return; } /** * EN: If error happened before, just wait until the resending work finishes by another thread * and close the current socket CN: 如果发现当前连接有error-response,加锁等待,直到另外一个线程把重发做完后再继续发送 */ synchronized (lock) { if (errorHappendedLastConn) { closeSocket(socket); socket = null; } byte[] data = notification.generateData(plBytes); boolean isSuccessful = false; int retries = 0; while (retries < maxRetries) { try { boolean exceedIntervalTime = lastSuccessfulTime > 0 && (System.currentTimeMillis() - lastSuccessfulTime) > intervalTime; if (exceedIntervalTime) { closeSocket(socket); socket = null; } if (socket == null || socket.isClosed()) { socket = createNewSocket(); } OutputStream socketOs = socket.getOutputStream(); socketOs.write(data); socketOs.flush(); isSuccessful = true; break; } catch (Exception e) { logger.error(connName + " " + e.getMessage(), e); closeSocket(socket); socket = null; } retries++; } if (!isSuccessful) { logger.error(String.format("%s Notification send failed. %s", connName, notification)); return; } else { logger.info( String.format( "%s Send success. count: %s, notificaion: %s", connName, notificaionSentCount.incrementAndGet(), notification)); notificationCachedQueue.add(notification); lastSuccessfulTime = System.currentTimeMillis(); if (notificationCachedQueue.size() > maxCacheLength) { notificationCachedQueue.poll(); } } } if (isFirstWrite) { isFirstWrite = false; /** * EN: When we create a socket, just a TCP/IP connection created. After we wrote data to the * stream, the SSL connection had been created. Now, it's time to read data from InputStream * CN: createSocket时只建立了TCP连接,还没有进行SSL认证,第一次写完数据后才真正完成认证。所以此时才开始 监听InputStream */ startErrorWorker(); } }