2014-01-22 97 views
0

我一直在尋找一種易於集成,簡單且輕量級的APNS(Apple推送通知服務)Java實現。APNS使用SOCKS支持的Java簡單實現(Apple Push Notification Service)

2個Java庫是(同樣?)流行:

  • javapns
  • java的APNS。

兩者都非常臃腫和複雜的整合,雖然他們(通常)聲稱它非常簡單。這兩個庫聲稱SOCKS代理支持,但我沒有設法得到它的工作,並在數小時後挖掘源代碼,並做了很多嘗試,我正在尋找另一種解決方案。

任何人都有一個Java簡單的實現呢?我認爲應該有可能僅在一個班級中提供功能性。 請注意我需要SOCKS代理支持。

回答

0

我終於寫了我自己的單類實現通過APNS發送通知。

以下是代碼,希望對您有所幫助。 請注意,通知的負載格式(標題,文本,聲音等)不在此處,也不是用於發送到很多智能手機的排隊。 此實現可以使用或不使用SOCKS代理,請參閱代碼以獲取詳細信息。

public class APNSHelper 
{ 
private static SSLContext sslContext; 
private static SSLSocketFactory sslSocketFactory; 
private static SSLSocket sslSocket; 
private static DataOutputStream dataOutputStream; 

private static final String KEYSTORE_TYPE = "PKCS12"; 
private static final String KEY_ALGORITHM = "sunx509"; 
private final static byte COMMAND = 0; 

private static long lastSucessfulSocketUsageMillis = 0L; 

private static void initSSL() throws Exception 
{ 
    Logger.debug("ApnsHelper.initSSL() begin"); 
    try 
    { 
     FileInputStream stream = new FileInputStream(Constants.IOS_CERTIFICATE_PATH); 
     final KeyStore lks = KeyStore.getInstance(KEYSTORE_TYPE); 
     lks.load(stream, Constants.IOS_CERTIFICATE_PASSWORD.toCharArray()); 
     final KeyManagerFactory lkmf = KeyManagerFactory.getInstance(KEY_ALGORITHM); 
     lkmf.init(lks, Constants.IOS_CERTIFICATE_PASSWORD.toCharArray()); 
     final TrustManagerFactory ltmf = TrustManagerFactory.getInstance(KEY_ALGORITHM); 
     ltmf.init((KeyStore)null); 
     sslContext = SSLContext.getInstance("TLS"); 
     sslContext.init(lkmf.getKeyManagers(), ltmf.getTrustManagers(), null); 
     sslSocketFactory = sslContext.getSocketFactory(); 
    } 
    catch(Exception e) 
    { 
     Logger.error("ApnsHelper.initSSL: " + e); 
     throw e; 
    } 
    Logger.debug("ApnsHelper.initSSL() end"); 
} 

private static Socket getSocket() throws Exception 
{ 
    Logger.debug("ApnsHelper.getSocket() begin"); 

    if (sslSocketFactory == null) initSSL(); 

    if (sslSocket != null) 
    { 
     try 
     { 
      dataOutputStream.close(); 
      sslSocket.close(); 
     } 
     catch(Exception e) 
     { 
      Logger.error("ApnsHelper.getSocket(): closing sslSocket: " + e); 
     } 
     dataOutputStream = null; 
     sslSocket = null; 
    } 

    try 
    { 
     Socket infraSocket = null; 
     if (Constants.IOS_PUSH_SOCKS_PROXY_HOST != null && Constants.IOS_PUSH_SOCKS_PROXY_HOST.length() > 0) 
     { 
      Logger.debug("ApnsHelper.getSocket(): with SOCKS PROXY=" + Constants.IOS_PUSH_SOCKS_PROXY_HOST + ":" + Constants.IOS_PUSH_SOCKS_PROXY_PORT); 

      InetSocketAddress proxyAddr = new InetSocketAddress(Constants.IOS_PUSH_SOCKS_PROXY_HOST, Constants.IOS_PUSH_SOCKS_PROXY_PORT); 
      Proxy proxy = new Proxy(Proxy.Type.SOCKS, proxyAddr); 
      infraSocket = new Socket(proxy); 
     } 
     else 
     { 
      Logger.debug("ApnsHelper.getSocket(): NO proxy"); 

      // NO SOCKS version 
      infraSocket = new Socket(); 
     } 

     InetSocketAddress targetAddr = new InetSocketAddress(Constants.IOS_PUSH_GATEWAY_HOST, Constants.IOS_PUSH_GATEWAY_PORT); 
     infraSocket.connect(targetAddr); 
     sslSocket = (SSLSocket) sslSocketFactory.createSocket(infraSocket, Constants.IOS_PUSH_GATEWAY_HOST, Constants.IOS_PUSH_GATEWAY_PORT, true); 

     Logger.debug("ApnsHelper.getSocket(): starting SSL handshake"); 
     sslSocket.startHandshake(); 
     Logger.debug("ApnsHelper.getSocket(): ended SSL handshake"); 
    } 
    catch(Exception e) 
    { 
     Logger.error("ApnsHelper.getSocket(): " + e); 
     throw e; 
    } 

    Logger.debug("ApnsHelper.getSocket() end"); 

    return sslSocket; 
} 

private static int hexValue(final char c) throws Exception 
{ 
    if ('0' <= c && c <= '9') return (c - '0'); 
    if ('a' <= c && c <= 'f') return (c - 'a') + 10; 
    if ('A' <= c && c <= 'F') return (c - 'A') + 10; 

    Logger.error("Invalid hex char='" + c + "'"); 
    throw new Exception("Invalid hex char='" + c + "'"); 
} 

public static synchronized void apnsPush(String mobileUIDID, String payLoad) 
{ 
    Logger.debug("ApnsHelper.apnsPush(mobileUIDID=" + mobileUIDID + ", payLoad=" + payLoad+ ") begin"); 

    int ltries = 0; 
    while(ltries < 3) 
    { 
     try 
     { 
      if (sslSocket == null || lastSucessfulSocketUsageMillis + Constants.IOS_PUSH_STALLED_MAX_TIME < System.currentTimeMillis()) 
      { 
       getSocket(); 
      } 
      dataOutputStream = new DataOutputStream(new BufferedOutputStream(sslSocket.getOutputStream())); 

      byte[] lpayLoad = payLoad.getBytes("UTF-8"); 
      final byte[] deviceId = new byte[mobileUIDID.length()/2]; 
      for (int i = 0; i < deviceId.length; i++) deviceId[i] = (byte) ((hexValue(mobileUIDID.charAt(2*i)) * 16 + hexValue(mobileUIDID.charAt(2*i + 1)))); 

      dataOutputStream.writeByte(COMMAND); 
      dataOutputStream.writeShort(deviceId.length); 
      dataOutputStream.write(deviceId); 
      dataOutputStream.writeShort(lpayLoad.length); 
      dataOutputStream.write(lpayLoad); 

      dataOutputStream.flush(); 
      lastSucessfulSocketUsageMillis = System.currentTimeMillis(); 
      Logger.debug("ApnsHelper.apnsPush(): sent message, mobileUIDID=" + mobileUIDID + ", payLoad=" + payLoad); 
      break; 
     } 
     catch(Exception e) 
     { 
      Logger.error("ApnsHelper.apnsPush(): " + e); 
      ltries++; 
     } 
    } 
    Logger.debug("ApnsHelper.apnsPush(mobileUIDID=" + mobileUIDID + ", payLoad=" + payLoad+ ") end"); 
} 

} }」

相關問題