个推简介 官方文档
个推是商用级的移动应用消息推送云服务解决方案,客户端SDK支持Android和iOS两大平台。
服务端接入步骤
<dependency>
<groupId>com.gexin.platform</groupId>
<artifactId>gexin-rp-sdk-http</artifactId>
<version>4.1.0.5</version>
</dependency>
消息发送流程
1.将需要发送的消息储存在数据库中 ,其中client_id是APP端接入个推后生成的id,需要app端提供(登录时,保存在数据库)
-- 个推消息表
CREATE TABLE `T_PUSH_MSG` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`proc_key` varchar(32) NOT NULL DEFAULT '',
`client_id` varchar(32) NOT NULL DEFAULT '' COMMENT '客户端id,APP端提供',
`client_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '客户端类型:0-android;1-ios',
`content` varchar(1000) NOT NULL DEFAULT '' COMMENT '消息内容',
`ios_alert_msg` varchar(128) NOT NULL DEFAULT '' COMMENT 'IOS专用',
`create_time` datetime NOT NULL COMMENT '创建时间',
`push_time` datetime DEFAULT NULL COMMENT '推送时间',
`push_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '推送状态:0-未推送;1-推送成功;2-推送失败;3-服务器响应异常;',
`push_result_desc` varchar(100) NOT NULL DEFAULT '' COMMENT '推送结果说明',
`push_loop` tinyint(4) NOT NULL DEFAULT '0' COMMENT '推送轮数',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=358 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='个推消息表';
2.启动定时任务扫描数据库,调用个推SDK将消息发送到个推服务器。 (注:ios端只支持透传消息)
常量说明
//常量说明
public final class CommonConstant {
/**
* 推送状态:0-未推送;1-推送成功;2-推送失败;3-服务器响应异常
*/
public static final class PUSH_STATUS {
public static final byte NOT_PUSH = 0;
public static final byte SUCCESS = 1;
public static final byte ERROR_PUSH = 2;
public static final byte ERROR_SERVER = 3;
}
/**
* 个推信息
*/
public static final class GE_TUI {
/**
* 每个应用都对应一个唯一的AppID
*/
public static final String APPID = "getui.appId";
/**
* SDK 与服务器端通过 Appkey 互相识别
*/
public static final String APPKEY = "getui.appKey";
/**
* 服务端API鉴权码 masterSecret
*/
public static final String MASTER_SECRET = "getui.masterSecret";
/**
* 个推开关
*/
public static final String ENABLE = "getui.enable";
public static final String OK = "ok";
}
}
定时任务
//定时扫描数据库 将消息发送到个推服务器
public void appMsgPush() {
//个推开关
if (!Boolean.parseBoolean(WebConfig.DBConfig.get(CommonConstant.GE_TUI.ENABLE))) {
return;
}
//查询需要发送的消息(未推送/推送失败且小于6轮)
List<TPushMsgPo> msgPos = pushMsgDao.selectAppMsg();
if (msgPos.size() == 0) {
return;
}
Date curTime = new Date();
for (TPushMsgPo msgPo : msgPos) {
msgPo.setPushLoop((byte) (msgPo.getPushLoop() + 1));
msgPo.setPushTime(curTime);
try {
String result = appPushClient.pushToSingle(msgPo);
//保存 解析 个推服务器的响应
msgPo.setPushResultDesc(result);
GeTuiPo geTuiPo = JSONObject.parseObject(result, GeTuiPo.class);
if (geTuiPo != null) {
if (CommonConstant.GE_TUI.OK.equals(geTuiPo.getResult())) {
msgPo.setPushStatus(CommonConstant.PUSH_STATUS.SUCCESS);
} else {
msgPo.setPushStatus(CommonConstant.PUSH_STATUS.ERROR_PUSH);
}
}
} catch (Exception e) {
msgPo.setPushStatus(CommonConstant.PUSH_STATUS.ERROR_SERVER);
logger.error("个推服务器出错", e);
}
}
pushMsgDao.updateBatch(msgPos);
}
接口:调用SDK推送
public interface AppPushClientService {
/**
* 对单个用户推送消息
*
* @param msgPos
* @return
*/
public String pushToSingle(TPushMsgPo msgPos);
/**
* 批量单推
* <p>
* 当单推任务较多时,推荐使用该接口,可以减少与服务端的交互次数。
*
* @param msgPos
*/
public void pushToSingleBatch(List<TPushMsgPo> msgPos);
}
接口实现
/**
* 个推app消息推送
*/
@Service
public class AppPushClientServiceImpl implements AppPushClientService {
private static final Logger logger = LoggerFactory.getLogger(AppPushClientServiceImpl.class);
/**
* 每个应用都对应一个唯一的AppID
*/
private static String appId;
/**
* SDK 与服务器端通过 Appkey 互相识别
*/
private static String appKey;
/**
* 服务端API鉴权码
*/
private static String masterSecret;
/**
* 个推开关
*/
private static boolean enable;
/**
* 批量单传使用
*/
private static IGtPush push;
public AppPushClientServiceImpl() {
appId = WebConfig.DBConfig.get(CommonConstant.GE_TUI.APPID);
appKey = WebConfig.DBConfig.get(CommonConstant.GE_TUI.APPKEY);
masterSecret = WebConfig.DBConfig.get(CommonConstant.GE_TUI.MASTER_SECRET);
enable = Boolean.parseBoolean(WebConfig.DBConfig.get(CommonConstant.GE_TUI.ENABLE));
if (!enable) {
return;
}
push = new IGtPush(appKey, masterSecret);
}
/**
* 对单个用户推送消息
*
* @return
*/
@Override
public String pushToSingle(TPushMsgPo msgPo) {
AbstractTemplate template = getTransmissionTemplate(msgPo.getContent());
// 单推消息类型
SingleMessage message = getSingleMessage(template);
Target target = new Target();
target.setAppId(appId);
target.setClientId(msgPo.getClientId());
IPushResult ret = null;
try {
ret = push.pushMessageToSingle(message, target);
} catch (RequestException e) {
logger.error("消息发送失败,尝试1次重发", e);
ret = push.pushMessageToSingle(message, target, e.getRequestId());
}
if (ret != null) {
JSONObject jsonObject = new JSONObject();
jsonObject.putAll(ret.getResponse());
return jsonObject.toJSONString();
} else {
return "服务器响应异常";
}
}
/**
* 透传消息,消息传递到客户端只有消息内容,展现形式由客户端自行定义
* 注:ios端只支持透传消息
*
* @param content
* @return
*/
private static TransmissionTemplate getTransmissionTemplate(String content) {
TransmissionTemplate template = new TransmissionTemplate();
template.setAppId(appId);
template.setAppkey(appKey);
//透传消息设置,1为强制启动应用,客户端接收到消息后就会立即启动应用;2为等待应用启动
template.setTransmissionType(2);
template.setTransmissionContent(content);
return template;
}
private static SingleMessage getSingleMessage(AbstractTemplate template) {
SingleMessage message = new SingleMessage();
message.setData(template);
// 设置消息离线,并设置离线时间
message.setOffline(true);
// 离线有效时间,单位为毫秒
message.setOfflineExpireTime(72 * 3600 * 1000);
message.setPriority(1);
// 判断客户端是否wifi环境下推送。1为仅在wifi环境下推送,0为不限制网络环境,默认不限
message.setPushNetWorkType(0);
return message;
}
/**
* 批量单推
* <p>
* 当单推任务较多时,推荐使用该接口,可以减少与服务端的交互次数。
*/
@Override
public void pushToSingleBatch(List<TPushMsgPo> msgPos) {
IBatch batch = push.getBatch();
IPushResult ret = null;
try {
//构建客户a的透传消息a
for (TPushMsgPo msgPo : msgPos) {
constructClientTransMsg(msgPo.getClientId(), batch, msgPo.getContent());
}
ret = batch.submit();
} catch (Exception e) {
e.printStackTrace();
try {
ret = batch.retry();
} catch (IOException ex) {
ex.printStackTrace();
}
}
if (ret != null) {
System.out.println(ret.getResponse().toString());
} else {
System.out.println("服务器响应异常");
}
}
private static void constructClientTransMsg(String cid, IBatch batch, String content) throws Exception {
AbstractTemplate template = getTransmissionTemplate(content);
SingleMessage message = getSingleMessage(template);
// 设置推送目标,填入appid和clientId
Target target = new Target();
target.setAppId(appId);
target.setClientId(cid);
batch.add(message, target);
}
}
3.个推服务器对APP进行消息推送。