当前位置: 首页 > 工具软件 > JavaPNS > 使用案例 >

APNS推送的另一种更简易的方式--javaPNS

薛扬
2023-12-01

APNS推送常用的框架有pushy和javaPNS两种,pushy较之javaPNS功能更为全面,但是在部署WEB项目的时候却出现了问题。pushy的运行需要制定命令行参数,需要替换虚拟机中的包,这对一个已经上线的、部署在tomcat上的javaweb项目来说不太友好,因此我最终选择了javaPNS这种更为简易的框架来实现APNS推送业务。

一、项目所需的jar包

这里才用maven的形式来依赖jar包

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.keisdom.myapns</groupId>
	<artifactId>myapns</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<dependencies>
		<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on -->
		<!--<dependency>
			<groupId>org.bouncycastle</groupId>
			<artifactId>bcprov-jdk15on</artifactId>
			<version>1.51</version>
		</dependency>--!>

		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.1</version>
		</dependency>

		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.7.21</version>
		</dependency>

		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-simple</artifactId>
			<version>1.7.25</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>com.github.fernandospr</groupId>
			<artifactId>javapns-jdk16</artifactId>
			<version>2.2.1</version>
		</dependency>

	</dependencies>
</project>

第一个被注释掉的包会产生一些误区,有些教程里面会导入这个包,在一般的程序中运行也不会出现问题。但是如果tomcat设置的最大空间没有那么大,或者刚好达到临界值了,就会出现栈溢出的问题。原因在于bcprov-jdk15on的包和javapns-jdk16的包互相的引用,导致循环引用包,最终会导致栈溢出的问题,只需要把bcprov-jdk15on的包给去掉就行了,javapns-jdk16已经依赖了这个包,就不用再重复依赖了。

二、消息的定制

javapns除去一些固定的发送的消息消息之外,也可以发送自定义消息头的消息,需要调用PushNotificationPayload的Payload.addCustomDictionary(String name, String value)方法。

如果需要发送自定义的消息,需要一个类继承Payload类,可以自己加属性和重写Payload中的方法,只要规格复合ios的json字符串的格式。

三、消息的响应

如果不添加消息的响应,发送的消息就会像石沉大海一样,即不知道消息是否正确发送给了apns服务器,也不知道apns是否已经将消息转发给了ios设备。因此,需要添加响应的方法,这里不使用监听去实现消息响应,而直接调用javaPNS的方法来接收消息的响应。

1.消息是否成功发给了apns服务器

由PushNotificationManager调用sendNotification(Device device, Payload payload, boolean closeAfter) 之后,会返回一个PushedNotification的对象,这个对象即可以调用相应的方法来获取响应。PushedNotification的isSuccessful()方法可以判断消息是否成功发送给了apns服务器。

2.消息是否已经由apns服务器发送给了ios设备

PushedNotification的getResponse()方法可以获得apns服务器发送消息的响应,返回一个ResponsePacket的对象,判断此对象是否为空且调用isErrorResponsePacket()方法返回true,说明消息推送失败了,这时应当作对应的处理。

最后,源码附上,临时写的,如果有出错,请谅解

package testapns;

import org.apache.commons.lang3.StringUtils;
import org.json.JSONException;

import javapns.communication.exceptions.CommunicationException;
import javapns.communication.exceptions.KeystoreException;
import javapns.devices.Device;
import javapns.devices.implementations.basic.BasicDevice;
import javapns.notification.AppleNotificationServerBasicImpl;
import javapns.notification.PushNotificationManager;
import javapns.notification.PushNotificationPayload;
import javapns.notification.PushedNotification;
import javapns.notification.ResponsePacket;

public class PushPNS {

	public static void main(String[] args) {
		try {
			String token ="your token";
			int badge=1;
			String sound="defalt";
			//String url = "dev.p12";
			String url = "G:\\dev.12";
			String password = "123456";
			PushNotificationPayload payload=new PushNotificationPayload();
			payload.addAlert("您有一个视频呼叫");
			payload.addBadge(badge);
			payload.addCustomDictionary("remote_id", "11");
			payload.addCustomDictionary("type", "video");
			if(!StringUtils.isEmpty(sound)) {
				payload.addSound(sound);
			}
			PushNotificationManager pushManager=new PushNotificationManager();
			pushManager.initializeConnection(new AppleNotificationServerBasicImpl(url, password, false));
			//List<PushedNotification> notifications=new ArrayList<PushedNotification>();
			Device device=new BasicDevice();
			device.setToken(token);
			PushedNotification notification=pushManager.sendNotification(device, payload,true);
			if(notification.isSuccessful()) {
				ResponsePacket theErrorResponse = notification.getResponse();
				if(theErrorResponse != null && theErrorResponse.isErrorResponsePacket()) {
					System.out.println("APNS server cant send message to IOS");
					pushManager.stopConnection();
				}
				pushManager.stopConnection();
			}else {
				pushManager.stopConnection();
				System.out.println("cannot send message to APNS server");
			}
		} catch (JSONException e) {
			e.printStackTrace();
		} catch (CommunicationException e) {
			e.printStackTrace();
		} catch (KeystoreException e) {
			e.printStackTrace();
		}
	}

}


 类似资料: