支持SOCKS的APNS Java简单实现(苹果推送通知服务)
我一直在寻找一个易于集成、简单轻量级的APNS(Apple推送通知服务)Java实现 2个java库(同样?)很流行:支持SOCKS的APNS Java简单实现(苹果推送通知服务),java,ios,apple-push-notifications,socks,Java,Ios,Apple Push Notifications,Socks,我一直在寻找一个易于集成、简单轻量级的APNS(Apple推送通知服务)Java实现 2个java库(同样?)很流行: javapns java apns 两者都非常臃肿,集成起来非常复杂,尽管它们(通常)声称这非常简单。这两个库都声称支持SOCKS代理,但我没有设法让它正常工作,在几个小时的挖掘源代码和多次尝试后,我正在寻找另一个解决方案 有人有这样的Java简单实现吗?我认为应该可以在一个类中提供功能性。 请注意,我需要SOCKS代理支持。我终于编写了自己的单类实现,用于通过APN发送通
- javapns
- java apns
请注意,我需要SOCKS代理支持。我终于编写了自己的单类实现,用于通过APN发送通知 下面是代码,希望对您有所帮助。 请注意,通知的有效负载格式(标题、文本、声音等)不在这里,发送到许多智能手机的队列也不在这里。 此实现可以使用SOCKS代理,也可以不使用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");
}
public类APNSHelper
{
专用静态SSLContext SSLContext;
私有静态SSLSocketFactory SSLSocketFactory;
专用静态SSLSocket SSLSocket;
私有静态DataOutputStream DataOutputStream;
私有静态最终字符串KEYSTORE_TYPE=“PKCS12”;
私有静态最终字符串密钥\u算法=“sunx509”;
私有最终静态字节命令=0;
私有静态long-LastSuccessfulSocketUsageMillis=0L;
私有静态void initSSL()引发异常
{
debug(“ApnsHelper.initSSL()begin”);
尝试
{
FileInputStream=新的FileInputStream(Constants.IOS\u CERTIFICATE\u PATH);
最终密钥库lks=KeyStore.getInstance(密钥库类型);
load(stream,Constants.IOS_CERTIFICATE_PASSWORD.toCharArray());
final KeyManagerFactory lkmf=KeyManagerFactory.getInstance(KEY_算法);
init(lks,Constants.IOS_CERTIFICATE_PASSWORD.toCharArray());
final TrustManagerFactory ltmf=TrustManagerFactory.getInstance(KEY_算法);
ltmf.init((密钥库)null);
sslContext=sslContext.getInstance(“TLS”);
init(lkmf.getKeyManager(),ltmf.getTrustManager(),null);
sslSocketFactory=sslContext.getSocketFactory();
}
捕获(例外e)
{
Logger.error(“ApnsHelper.initSSL:+e”);
投掷e;
}
debug(“ApnsHelper.initSSL()end”);
}
私有静态套接字getSocket()引发异常
{
debug(“ApnsHelper.getSocket()begin”);
if(sslSocketFactory==null)initSSL();
如果(sslSocket!=null)
{
尝试
{
dataOutputStream.close();
sslSocket.close();
}
捕获(例外e)
{
Logger.error(“ApnsHelper.getSocket():关闭sslSocket:”+e);
}
dataOutputStream=null;
sslSocket=null;
}
尝试
{
Socket-infraSocket=null;
if(Constants.IOS\u PUSH\u SOCKS\u PROXY\u HOST!=null&&Constants.IOS\u PUSH\u SOCKS\u PROXY\u HOST.length()>0)
{
Logger.debug(“ApnsHelper.getSocket():with SOCKS PROXY=“+Constants.IOS\u PUSH\u SOCKS\u PROXY\u HOST+”:“+Constants.IOS\u PUSH\u SOCKS\u PROXY\u PORT”);
InetSocketAddress proxyAddr=新的InetSocketAddress(Constants.IOS\u PUSH\u SOCKS\u PROXY\u主机,Constants.IOS\u PUSH\u SOCKS\u PROXY\u端口);
Proxy Proxy=新代理(Proxy.Type.SOCKS,proxyAddr);
infraSocket=新套接字(代理);
}
其他的
{
debug(“ApnsHelper.getSocket():无代理”);
//无袜子版本
infraSocket=新套接字();
}
InetSocketAddress targetAddr=新的InetSocketAddress(Constants.IOS\u PUSH\u GATEWAY\u主机,Constants.IOS\u PUSH\u GATEWAY\u端口);
infraSocket.connect(目标地址);
sslSocket=(sslSocket)sslSocketFactory.createSocket(infraSocket,Constants.IOS\u PUSH\u GATEWAY\u主机,Constants.IOS\u PUSH\u GATEWAY\u端口,true);
debug(“ApnsHelper.getSocket():启动SSL握手”);
sslSocket.startHandshake();
debug(“ApnsHelper.getSocket():结束SSL握手”);
}
捕获(例外e)
{
Logger.error(“ApnsHelper.getSocket():”+e);
投掷e;
}
debug(“ApnsHelper.getSocket()end”);
返回sslSocket;
}
私有静态int hexValue(最终字符c)引发异常
{
如果('0'