您的位置:首页 > 编程语言 > Java开发

Java NotNoop推送方式实例

2015-07-10 11:49 573 查看
先熟悉一下主要的几个接口或者类:

com.notnoop.apns.internal包:


AbstractApnsService:一个抽象类,实现了ApnsService接口。主要包含三种表现形式:



ApnsServiceImpl:基础消息处理类。


BatchApnsService:批量消息处理类,默认每隔5秒钟,执行一次批量推送。


QueuedApnsService:队列消息处理类,即使用阻塞队列方式处理消息。


ApnsConnection:作为应用连接到苹果APNS服务的接口。主要包含两种表现形式:

ApnsConnectionImpl:基础连接类,实现了ApnsConnection接口。主要处理从消息发送到收到回执后的一系列过程。
ApnsPooledConnection:以多线程的方式管理连接池。

ReconnectPolicies:Socket的连接策略,分为三种:Never、Always、EveryHalfHour。
Utilities:顾名思义,就是一个工具类,包含一些工具和常量。

com.notnoop.apns包:


APNS:作为与APNS交互的主要类,用于构建Payload和ApnsService。
ApnsDelegate:委托接口,委托收到苹果服务器的状态通知后的处理。如果消息实际到达了客户端,则服务器不会收到任何的状态通知。

ApnsDelegateAdapter:代理适配器,继承了ApnsDelegate接口,但不做任何事。

ApnsNotification:通知信息接口,包含通知的所有信息。

ApnsService:APNS服务接口。

ApnsServiceBuilder:ApnsService的生成器。

DeliveryError:APNS可能返回的错误。

EnhancedApnsNotification:通知信息类,继承了ApnsNotification接口。

PayloadBuilder:Payload生成器。

ReconnectPolicy:重连策略接口,基于ReconnectPolicies。

示例:

package com.xxx.pushmsg.service.ios.impl;

import com.xxx.common.constant.CacheConstant;
import com.xxx.common.utils.RedisUtils;
import com.xxx.common.utils.StringUtil;
import com.xxx.pushmsg.service.ios.IosPushMsgService;
import com.notnoop.apns.APNS;
import com.notnoop.apns.ApnsDelegate;
import com.notnoop.apns.ApnsService;
import com.notnoop.apns.PayloadBuilder;
import com.notnoop.exceptions.NetworkIOException;
import javapns.notification.transmission.NotificationProgressListener;
import javapns.notification.transmission.NotificationThread;
import javapns.notification.transmission.NotificationThreads;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class IosPushMsgServiceImpl implements IosPushMsgService {
private static final Logger log = LoggerFactory.getLogger(IosPushMsgServiceImpl.class);
private static final Logger logPush = LoggerFactory.getLogger("push_arrival_rate");
public static final ConcurrentHashMap<Long, Integer> msgStateMap = new ConcurrentHashMap<Long, Integer>();
@Value("${priest.pushmsg.production}")

//是否是生产环境
private boolean production;

@Value("${priest.pushmsg.certificate.file.name}")

//证书文件地址
private String certificateName;

ApnsService service = null;
@Resource
private RedisUtils redisUtils;

//连接池大小
private int capacity = 20;
@Resource
private ApnsDelegate delegate;
@PostConstruct
public void init() {
String password = "123456"; // 证书密码
try {

//初始化服务类型为基本消息处理类型,并且连接设置为连接池
service = APNS.newService().withCert(certificateName, password)
.asPool(capacity).withDelegate(delegate).withAppleDestination(production).build();
} catch (Exception e) {
log.error("Init error Class::IosPushMsgServiceImpl Method::init", e);
}

}

public void stopPush(Long msgId){

}

public boolean pushOffLineMessageNotnoop(Map<String, String> tokenMessgae, Map<String, Object> mapCustom) {

if (MapUtils.isEmpty(tokenMessgae)) {
return true;
}

//铃音,微信等应用实现语音呼叫时使用的方式是将此铃音设置为30秒的长铃音,最大限制为30秒。
String sound = "msg.wav"; try { this.send(tokenMessgae, null, sound, mapCustom); } catch (Exception ex) { log.error("OffLineMessageNotnoop Multi error Class::IosPushMsgServiceImpl Method::pushOffLineMessageNotnoop Param::message"+ " Param::tokenMessgae:" + tokenMessgae + ",mapCustom:" + mapCustom, ex); } return true; }

//发送方法
private void send(Map<String, String> tokenMessage, String launchImage, String sound, Map<String, Object> mapCustom) {

try {
Long nowStart = System.currentTimeMillis();
Map<String, String> mapCount = this.redisUtils.hGetAll(CacheConstant.CACHE_PREFIX_IOS_GROUP_PUSHMSG_COUNT);
//发送消息
Iterator<String> it = tokenMessage.keySet().iterator();
while (it.hasNext()) {
Long nowStart111 = System.currentTimeMillis();
String token = it.next();

//因为标准的Token大小为64位,因此如果Token不符合规范则不推
if (token.length() < 64) {
continue;
}
String alert = tokenMessage.get(token);

//构造Payload
PayloadBuilder payloadBuilder = APNS.newPayload();
//拼装消息
payloadBuilder = payloadBuilder.alertBody(alert);

if (!StringUtils.isEmpty(launchImage)) {
payloadBuilder = payloadBuilder.launchImage(launchImage);
}
if (!StringUtils.isEmpty(sound)) {
payloadBuilder = payloadBuilder.sound(sound);
}
//裁剪消息
if (payloadBuilder.isTooLong()) {
payloadBuilder = payloadBuilder.shrinkBody();
}
payloadBuilder = payloadBuilder.forNewsstand();
//增加额外的信息
if(null != mapCustom)
payloadBuilder.customFields(mapCustom);
Integer count = 1;
if (mapCount.containsKey(token)) {
String countStr = mapCount.get(token);
count = StringUtil.isEmpty(countStr) ? 0 : Integer.valueOf(countStr);
if (count < 99) {
count = count + 1;
} else {
count = 99;
}
}

//设置小红圈上面的数字
payloadBuilder.badge(count);
//组装成json
String payload = payloadBuilder.build();

//发送消息
service.push(token, payload, new Date(System.currentTimeMillis() + 1000 * 1000));
Long nowEnd111 = System.currentTimeMillis();

//重组消息体,去除其中的Emoji,否则发送消息体会出现问题
String logContent = StringUtil.filterEmoji(alert).replaceAll("\r","").replaceAll("\n","");
this.redisUtils.hPut(CacheConstant.CACHE_PREFIX_IOS_GROUP_PUSHMSG_COUNT, token, count);
StringBuffer sb = new StringBuffer();
sb.append("{\"token\":");
sb.append("\"");
sb.append(token);
sb.append("\"");
sb.append(",\"content\":");
sb.append("{");
sb.append("\"content\":");
sb.append("\"");
sb.append(logContent);
sb.append("\"");
sb.append(",\"createTime\":");
sb.append(nowEnd111);
sb.append("}");
sb.append(",\"ret\":");
sb.append("{\"ret_code\":0}");
sb.append("}");
logPush.info(sb.toString());
}
Long nowEnd = System.currentTimeMillis();
log.info("IOSPushMsgSend Cost:" + (nowEnd - nowStart));
} catch (NetworkIOException e) {
log.error("Send Multi Error NetworkIOException At Class::IosPushMsgServiceImpl Method::send"
+ " Param::tokenMessage:" + tokenMessage, e);
if (e.toString().contains("certificate")) {
//shortMessageService.sendMessage(Long.MAX_VALUE, null, "15001257920", e.toString());
}
} catch (Exception ex) {
log.error("Send Multi Error Exception At Class::IosPushMsgServiceImpl Method::send"
+ " Param::tokenMessage:" + tokenMessage, ex);
} finally  {
}
}

public static final NotificationProgressListener DEBUGGING_PROGRESS_LISTENER = new NotificationProgressListener() {
public void eventThreadStarted(NotificationThread notificationThread) {
log.info("EventThreadStarted [EVENT]: thread #" + notificationThread.getThreadNumber() + " started with "
+ " devices beginning at message id #" + notificationThread.getFirstMessageIdentifier()
+ " At Class::NotificationProgressListener Method::eventThreadStarted" + notificationThread.getFailedNotifications());
}

public void eventThreadFinished(NotificationThread thread) {
log.info("EventThreadFinished [EVENT]: thread #" + thread.getThreadNumber() + " finished: pushed messages #"
+ thread.getFirstMessageIdentifier() + " to " + thread.getLastMessageIdentifier() + " toward " + " devices"
+ " At Class::NotificationProgressListener Method::eventThreadFinished" + thread.getFailedNotifications());
}

public void eventConnectionRestarted(NotificationThread thread) {
log.info("EventConnectionRestarted [EVENT]: connection restarted in thread #" + thread.getThreadNumber()
+ " because it reached " + thread.getMaxNotificationsPerConnection() + " notifications per connection"
+ " At Class::NotificationProgressListener Method::eventConnectionRestarted" + thread.getFailedNotifications());
}

public void eventAllThreadsStarted(NotificationThreads notificationThreads) {
log.info("EventAllThreadsStarted [EVENT]: all threads started: " + notificationThreads.getThreads().size()
+ " At Class::NotificationProgressListener Method::eventAllThreadsStarted" + notificationThreads.getFailedNotifications());
}

public void eventAllThreadsFinished(NotificationThreads notificationThreads) {
log.info("EventAllThreadsFinished [EVENT]: all threads finished: " + notificationThreads.getThreads().size()
+ " At Class::NotificationProgressListener Method::eventAllThreadsFinished" + notificationThreads.getFailedNotifications());
}

public void eventCriticalException(NotificationThread notificationThread, Exception exception) {
log.info("EventCriticalException [EVENT]: critical exception occurred: " + exception
+ " At Class::NotificationProgressListener Method::eventCriticalException" + notificationThread.getFailedNotifications());
}
};

public void setCapacity(int capacity) {
this.capacity = capacity;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: