淘先锋技术网

首页 1 2 3 4 5 6 7

因为工作需要,甲方单位使用极光推送总是出现用户收取不到推送消息,甲方要求我们使用个推。

因为我们访问网络的时候使用的是代理,所以个推提供的接口发送接口不能使用,所以需要重新写一个支持代理的http链接。目前项目中的个推使用流程如下:

目前使用的是群推:pushToList,群推第一步使用taskid ,taskid 就是我们的消息在推送平台对应的一个映射id,通过taskid 来找这个消息。第二部是发送消息。发送消息的流程和获取taskId的流程几乎是一致的,就是在发送的过程中,gt_action 传的参数不一样,获取taskid 时传的是getContentIdAction,而推送消息的时候使用的是pushMessageToListAction。

个推的推送过程是:

http 代理代码如下:

package com.ruim.ifsp.merser.util;

import com.alibaba.dubbo.common.utils.StringUtils;
import com.ruim.ifsp.log.IfspLoggerFactory;
import com.ruim.ifsp.merser.cache.CommonConstants;
import com.ruim.ifsp.utils.client.http.IfspHttpClientUtil;
import org.slf4j.Logger;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
/**
 * 个推
 * @author lxw
 * @deprecated 个推消息推送http链接
 */
public class IGtpushHttpClient extends IfspHttpClientUtil {

    private static Logger logger = IfspLoggerFactory.getLogger(JpushHttpClient.class);
    static String proxyIp = CommonConstants.getProperties("PROXY_IP");
    static String proxyProt = CommonConstants.getProperties("PROXY_PORT");

//    private static String appId = "TxzlIyCcfS9KuENjjP4ux1";
//    private static String appKey = "rAnoicfrNX7915IxPocAL2";
//    private static String masterSecret = "KFDNBNKAVj9bgykwvqgeA5";
//    static String host = "http://sdk.open.api.igexin.com/apiex.htm";
    private static String appId = CommonConstants.getProperties("IGTAPP_ID");//个推appid
    private static String appKey = CommonConstants.getProperties("IGTAPP_KEY");//应用appKey
    private static String masterSecret = CommonConstants.getProperties("IGTMASTER_SECRET");//应用证书号
    private static String host = CommonConstants.getProperties("IGTPUST_HOST");//个推送地址



    public static HttpURLConnection buildConnect(String Action) throws Exception {
        URL url = new URL(host);
        logger.info("开始初始化服务器连接...");
        logger.info("服务器地址:[ " + url + " ]");
        /**启用代理*/
        Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyIp, Integer.valueOf(proxyProt)));
        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(proxy);
        httpURLConnection.setConnectTimeout(30000);
        httpURLConnection.setReadTimeout(30000);
        httpURLConnection.setDoInput(true);
        httpURLConnection.setDoOutput(true);
        httpURLConnection.setUseCaches(false);
        httpURLConnection.setRequestProperty("Content-Type", "text/html;charset=UTF-8");
        httpURLConnection.setRequestProperty("Gt-Action", Action);
        httpURLConnection.setRequestMethod("POST");
        httpURLConnection.connect();
        logger.info("服务器连接完成...");
        return httpURLConnection;
    }

    public static void sendMsg(HttpURLConnection httpURLConnection,String message) throws Exception {
        logger.info("上送服务报文开始...");
        logger.info("上送报文:[" + message + "]");
        OutputStream outputStream = null;
        try {
            outputStream = httpURLConnection.getOutputStream();
            // 注意编码格式,防止中文乱码
            if (StringUtils.isNotEmpty(message)) {
                outputStream.write(message.getBytes("utf-8"));
            } else {
                outputStream.write("".getBytes());
            }
            if (null != outputStream)
                outputStream.close();
            logger.info("上送服务报文完成...");
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } finally {
            if (null != outputStream)
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
    }

    public static String receiveMsg(HttpURLConnection httpURLConnection) throws IOException {
        logger.debug("接收服务器响应报文开始...");
        InputStream in = null;
        StringBuilder sb = new StringBuilder(1024);
        BufferedReader br = null;
        String temp = null;
        int code = httpURLConnection.getResponseCode();
        if (200 == code) {
            in = httpURLConnection.getInputStream();
            br = new BufferedReader(new InputStreamReader(in, "utf-8"));
            while (null != (temp = br.readLine())) {
                sb.append(temp);
            }
        } else {
            in = httpURLConnection.getErrorStream();
            br = new BufferedReader(new InputStreamReader(in, "utf-8"));
            while (null != (temp = br.readLine())) {
                sb.append(temp);
            }
        }
        String str1 = sb.toString();
        logger.info("报文: [ " + str1 + " ] ");
        logger.info("接收服务器响应报文完成");
        return str1;
    }
}

推送消息代码:

package com.ruim.ifsp.merser.util;

import com.gexin.rp.sdk.base.IPushResult;
import com.gexin.rp.sdk.base.impl.*;
import com.gexin.rp.sdk.base.payload.APNPayload;
import com.gexin.rp.sdk.base.payload.Payload;
import com.gexin.rp.sdk.base.uitls.Base64Util;
import com.gexin.rp.sdk.base.uitls.LangUtil;
import com.gexin.rp.sdk.base.uitls.SignUtil;
import com.gexin.rp.sdk.http.IGtPush;
import com.gexin.rp.sdk.http.utils.GTConfig;
import com.gexin.rp.sdk.http.utils.ParamUtils;
import com.gexin.rp.sdk.template.LinkTemplate;
import com.gexin.rp.sdk.template.NotificationTemplate;
import com.ruim.ifsp.exception.BizException;
import com.ruim.ifsp.log.IfspLoggerFactory;
import com.ruim.ifsp.merser.cache.CommonConstants;
import com.ruim.ifsp.utils.message.IfspFastJsonUtil;
import com.ruim.ifsp.utils.verify.IfspDataVerifyUtil;
import org.slf4j.Logger;

import java.net.HttpURLConnection;
import java.time.format.TextStyle;
import java.util.*;

public class IGtpushThread extends Thread {

    private static Logger log = IfspLoggerFactory.getLogger(IGtpushThread.class);

    private static String appId = CommonConstants.getProperties("IGTAPP_ID");;
    private static String appKey = CommonConstants.getProperties("IGTAPP_KEY");
    private static String masterSecret = CommonConstants.getProperties("IGTMASTER_SECRET");
    private static String host = CommonConstants.getProperties("IGTPUST_HOST");

    private String alias;
    private String message;
    private String msgSendType;

    public IGtpushThread(String alias,String message,String msgSendType) {
//        super();
        this.alias = alias;
        this.message = message;
        this.msgSendType = msgSendType;
    }
    /**
     * If this thread was constructed using a separate
     * <code>Runnable</code> run object, then that
     * <code>Runnable</code> object's <code>run</code> method is called;
     * otherwise, this method does nothing and returns.
     * <p>
     * Subclasses of <code>Thread</code> should override this method.
     *
     * @see #start()
     * @see #stop()
     * @see #(ThreadGroup, Runnable, String)
     */
    @Override
    public void run() {
        IGTpushMsg(alias,message,msgSendType);
    }
    public void IGTpushMsg(String alias,String message,String msgSendType){

        String respMsg = new String();
        String[] arr = alias.split(",");
        // 通知透传模板 消息传递
        NotificationTemplate template = notificationTemplateDemo(message);
        ListMessage messages = new ListMessage();
        messages.setData(template);
        // 设置消息离线,并设置离线时间
        messages.setOffline(true);
        // 离线有效时间,单位为毫秒,可选
        messages.setOfflineExpireTime(24 * 1000 * 3600);
        // 配置推送目标
        List targets = new ArrayList();
        // taskId用于在推送时去查找对应的message
        try{
            String taskId = getListAppContentId(messages,null);
            Map<String,Object> postData = null;
            for (int i = 0; i < arr.length; i++) {
                Target target = new Target();
                target.setAppId(appId);
                target.setAlias(arr[i]);
                targets.add(target);
                //每50个别名(CID)推送一次
                if (arr.length>50&&targets.size()==50){
                    postData =pushMessageToList(taskId,targets);
                    Map<String,Object> response = httpResponse(postData);
                    if (!"ok".equals(response.get("result"))){
                        response = httpResponse(postData);
                        respMsg = IfspFastJsonUtil.mapTOjson(response);
                        log.info("个推建议值推送结果是:"+respMsg);
                    }
                    targets.clear();
                }
            }
            if (targets.size()>0){
                postData =pushMessageToList(taskId,targets);
                Map<String,Object> response = httpResponse(postData);
                if (!"ok".equals(response.get("result"))){
                    response = httpResponse(postData);
                    respMsg = IfspFastJsonUtil.mapTOjson(response);
                    log.info("个推第二次推送结果是:"+respMsg);
                }
            }
        }catch (Exception e){
            log.error("个推推送失败,原因是:"+e.getMessage());
        }
    }
    public Map<String, Object> pushMessageToList(String contentId, List<Target> targetList) throws Exception{
        Map<String, Object> postData = new HashMap();
        postData.put("authToken", null);
        postData.put("action", "pushMessageToListAction");
        postData.put("appkey", appKey);
        postData.put("contentId", contentId);
        boolean needDetails = GTConfig.isPushListNeedDetails();
        postData.put("needDetails", needDetails);
        boolean async = GTConfig.isPushListAsync();
        postData.put("async", async);
        boolean needAliasDetails = GTConfig.isPushListNeedAliasDetails();
        postData.put("needAliasDetails", needAliasDetails);
        int limit;
        if (async && !needDetails) {
            limit = GTConfig.getAsyncListLimit();
        } else {
            limit = GTConfig.getSyncListLimit();
        }
        if (targetList.size() > limit) {
            throw new BizException("1000","target size:" + targetList.size() + " beyond the limit:" + limit);
        } else {
            List<String> clientIdList = new ArrayList();
            List<String> aliasList = new ArrayList();
            String appId = null;
            Iterator var12 = targetList.iterator();

            while(true) {
                Target target;
                do {
                    if (!var12.hasNext()) {
                        postData.put("appId", appId);
                        postData.put("clientIdList", clientIdList);
                        postData.put("aliasList", aliasList);
                        postData.put("type", 2);
                        return postData;
                    }

                    target = (Target)var12.next();
                    String targetCid = target.getClientId();
                    String targetAlias = target.getAlias();
                    if (targetCid != null && !"".equals(targetCid.trim())) {
                        clientIdList.add(targetCid);
                    } else if (targetAlias != null && !"".equals(targetAlias.trim())) {
                        aliasList.add(targetAlias);
                    }
                } while(appId != null && !"".equals(appId.trim()));

                appId = target.getAppId();
            }
        }
        //苹果参数组装

    }
    public NotificationTemplate notificationTemplateDemo(String message) {
        NotificationTemplate template = new NotificationTemplate();
        // 设置APPID与APPKEY
        template.setAppId(appId);
        template.setAppkey(appKey);
        // 设置通知栏标题与内容
        template.setTitle("");
        template.setText("");
//        // 配置通知栏图标
//        template.setLogo("icon.png");
        // 配置通知栏网络图标
//        template.setLogoUrl("");
        // 设置通知是否响铃,震动,或者可清除
//        template.setIsRing(true);
//        template.setIsVibrate(true);
//        template.setIsClearable(true);
        // 透传消息设置,1为强制启动应用,客户端接收到消息后就会立即启动应用;2为等待应用启动
        template.setTransmissionType(2);
        template.setTransmissionContent(message);
        //ios 消息推送
//        APNPayload apnPayload = new APNPayload();
//        APNPayload.SimpleAlertMsg alertMsg = new APNPayload.SimpleAlertMsg(message);
//        apnPayload.setAlertMsg(alertMsg);
//        template.setAPNInfo(apnPayload);
        return template;
    }
    public static void main(String[] args) throws Exception {
    	//单推测试
//        LinkTemplate template = linkTemplateDemo();
//        SingleMessage message = new SingleMessage();
//        message.setOffline(true);
//        // 离线有效时间,单位为毫秒,可选
//        message.setOfflineExpireTime(24 * 3600 * 1000);
//        message.setData(template);
//        // 可选,1为wifi,0为不限制网络环境。根据手机处于的网络情况,决定是否下发
//        message.setPushNetWorkType(0);
//        Target target = new Target();
//        target.setAppId(appId);
//        target.setAlias("201006700000010_18611111116");
//        IPushResult ret = null;
//        Map<String,Object> reqMap = getSingleMessagePostData(message,target,null);
//        String requestMsg = IfspFastJsonUtil.mapTOjson(reqMap);
//        long startTime=System.currentTimeMillis();
        HttpURLConnection client = null;
//        try {
//            HttpURLConnection client = null;
//            client = IGtpushHttpClient.buildConnect(reqMap.get("action").toString());
//            IGtpushHttpClient.sendMsg(client, requestMsg);
//            String respMsg =IGtpushHttpClient.receiveMsg(client);
//            client.disconnect();
//            Map<String,Object> responseDate = (Map<String, Object>) IfspFastJsonUtil.jsonTOmap(respMsg);
//            if ("sign_error".equals(responseDate.get("result"))){
//                Map<String,Object> post = new HashMap<>();
//                long timeStamp = System.currentTimeMillis();
//                String sign = SignUtil.getSign(appKey, masterSecret, timeStamp);
//                post.put("action", "connect");
//                post.put("appkey", appKey);
//                post.put("timeStamp", timeStamp);
//                post.put("sign", sign);
//                post.put("version", GTConfig.getSDKVersion());
//                client = IGtpushHttpClient.buildConnect(post.get("action").toString());
//                IGtpushHttpClient.sendMsg(client, IfspFastJsonUtil.mapTOjson(post).toString());
//                String resp = IGtpushHttpClient.receiveMsg(client);
//                Map<String,Object> respDate = (Map<String, Object>) IfspFastJsonUtil.jsonTOmap(resp);
//                reqMap.put("authToken",respDate.get("authtoken"));
//                client.disconnect();
//            }
//            client = IGtpushHttpClient.buildConnect(reqMap.get("action").toString());
            client.setRequestProperty("Gt-Action",reqMap.get("action").toString());
//            String reqMsg = IfspFastJsonUtil.mapTOjson(reqMap);
//            IGtpushHttpClient.sendMsg(client, reqMsg);
//            String respMseeage =IGtpushHttpClient.receiveMsg(client);
//
//        } catch (Exception e) {
//
            try {
                client = IGtpushHttpClient.buildConnect();
                IGtpushHttpClient.sendMsg(client, requestMsg);
                IGtpushHttpClient.receiveMsg(client);
            } catch (Exception e1) {
//                e.printStackTrace();
            }
//        }finally {
            if(client != null){
                client.disconnect();
            }
//        }
//        long endTime=System.currentTimeMillis();
//    }
//				群推测试
        // 通知透传模板
//        NotificationTemplate template = notificationTemplateDemo();
//        ListMessage message = new ListMessage();
//        message.setData(template);
//        // 设置消息离线,并设置离线时间
//        message.setOffline(true);
//        // 离线有效时间,单位为毫秒,可选
//        message.setOfflineExpireTime(24 * 1000 * 3600);
//        // 配置推送目标
//        List targets = new ArrayList();
//        Target target1 = new Target();
//        Target target2 = new Target();
//        target1.setAppId(appId);
//        target1.setAlias("201006700000010_18611111116");
//        targets.add(target1);
//        // taskId用于在推送时去查找对应的message
//        String taskId = getListAppContentId(message,null);
//        Map<String, Object> ret = pushMessageToList(taskId, targets);
        String requestMsg = IfspFastJsonUtil.mapTOjson(ret);
//        long startTime=System.currentTimeMillis();
//        HttpURLConnection client = null;
//        try {
//            ret.put("version", GTConfig.getSDKVersion());
//            ret.put("authToken",null);
//            String requestMsg = IfspFastJsonUtil.mapTOjson(ret);
//            client = IGtpushHttpClient.buildConnect(ret.get("action").toString());
//            IGtpushHttpClient.sendMsg(client, requestMsg);
//            String response = IGtpushHttpClient.receiveMsg(client);
//            client.disconnect();
//            Map<String,Object> responseDate = (Map<String, Object>) IfspFastJsonUtil.jsonTOmap(response);
//            if ("sign_error".equals(responseDate.get("result"))){
//                Map<String,Object> post = new HashMap<>();
//                long timeStamp = System.currentTimeMillis();
//                String sign = SignUtil.getSign(appKey, masterSecret, timeStamp);
//                post.put("action", "connect");
//                post.put("appkey", appKey);
//                post.put("timeStamp", timeStamp);
//                post.put("sign", sign);
//                post.put("version", GTConfig.getSDKVersion());
//                client = IGtpushHttpClient.buildConnect(post.get("action").toString());
//                IGtpushHttpClient.sendMsg(client, IfspFastJsonUtil.mapTOjson(post).toString());
//                String resp = IGtpushHttpClient.receiveMsg(client);
//                Map<String,Object> respDate = (Map<String, Object>) IfspFastJsonUtil.jsonTOmap(resp);
//                ret.put("authToken",respDate.get("authtoken"));
//                client.disconnect();
//            }
//            client = IGtpushHttpClient.buildConnect(ret.get("action").toString());
//            String reqMsg = IfspFastJsonUtil.mapTOjson(ret);
//            IGtpushHttpClient.sendMsg(client, reqMsg);
//            String respMseeage =IGtpushHttpClient.receiveMsg(client);
//            System.out.println(respMseeage);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }finally {
//            if(client != null){
//                client.disconnect();
//            }
//        }
    }
    private String getListAppContentId(Message message, String taskGroupName) {
        Map<String, Object> postData = new HashMap();
        Map<String, Object> response = null;
        if (taskGroupName != null) {
            postData.put("taskGroupName", taskGroupName);
        }
        postData.put("action", "getContentIdAction");
        postData.put("appkey", appKey);
        postData.put("clientData", Base64Util.getBASE64(message.getData().getTransparent().toByteArray()));
        postData.put("transmissionContent", message.getData().getTransmissionContent());
        postData.put("isOffline", message.isOffline());
        postData.put("offlineExpireTime", message.getOfflineExpireTime());
        postData.put("pushType", message.getData().getPushType());
        postData.put("type", 2);
        if (message instanceof ListMessage) {
            postData.put("contentType", 1);
        } else if (message instanceof AppMessage) {
            postData.put("contentType", 2);
            AppMessage appMessage = (AppMessage) message;
            ParamUtils.checkAppid(message, appMessage.getAppIdList());
            postData.put("appIdList", appMessage.getAppIdList());
            List<String> phoneTypeList = null;
            List<String> provinceList = null;
            List<String> tagList = null;
            new ArrayList();
            if (appMessage.getConditions() == null) {
                phoneTypeList = appMessage.getPhoneTypeList();
                provinceList = appMessage.getProvinceList();
                tagList = appMessage.getTagList();
                postData.put("phoneTypeList", phoneTypeList);
                postData.put("provinceList", provinceList);
                postData.put("tagList", tagList);
            } else {
                List<Map<String, Object>> conditions = appMessage.getConditions().getCondition();
            }

            postData.put("speed", appMessage.getSpeed());
            String pushTime = appMessage.getPushTime();
            if (pushTime != null && !pushTime.isEmpty()) {
                postData.put("pushTime", pushTime);
            }
        }
        postData.put("pushNetWorkType", message.getPushNetWorkType());
        //调用个推 获取绑定的个推平台信息绑定的id
        response = httpResponse(postData);
        String result = LangUtil.parseString(response.get("result"));
        String contentId = LangUtil.parseString(response.get("contentId"));
        if ("ok".equals(result) && contentId != null) {
            return contentId;
        } else {
            throw new RuntimeException("host:[" + host + "]获取contentId失败:" + result);
        }
    }

    /**
     * http 调用方法
     * @param postData
     * @return
     */
    public Map<String,Object> httpResponse(Map<String,Object> postData){

        HttpURLConnection client = null;
        String response = null;
        try {
            postData.put("version", GTConfig.getSDKVersion());
            postData.put("authToken",null);
            client = IGtpushHttpClient.buildConnect(postData.get("action").toString());
            IGtpushHttpClient.sendMsg(client, IfspFastJsonUtil.mapTOjson(postData).toString());
            response =IGtpushHttpClient.receiveMsg(client);
            client.disconnect();
            Map<String,Object> respData =(Map<String,Object>)IfspFastJsonUtil.jsonTOmap(response);
            if ("ok".equals(respData.get("result"))){
                return respData;
            }
            if("sign_error".equals(respData.get("result"))){
                long timeStamp = System.currentTimeMillis();
                String sign = SignUtil.getSign(appKey, masterSecret, timeStamp);
                Map<String, Object> postData1 = new HashMap();
                postData1.put("action", "connect");
                postData1.put("appkey", appKey);
                postData1.put("timeStamp", timeStamp);
                postData1.put("sign", sign);
                postData1.put("version", GTConfig.getSDKVersion());
                client = IGtpushHttpClient.buildConnect(postData1.get("action").toString());
                IGtpushHttpClient.sendMsg(client, IfspFastJsonUtil.mapTOjson(postData1).toString());
                response =IGtpushHttpClient.receiveMsg(client);
                client.disconnect();

                Map<String,Object> respdata =(Map<String,Object>)IfspFastJsonUtil.jsonTOmap(response);
                //放入authToken 值
                postData.put("authToken",respdata.get("authtoken"));

                client = IGtpushHttpClient.buildConnect(postData.get("action").toString());
                IGtpushHttpClient.sendMsg(client, IfspFastJsonUtil.mapTOjson(postData).toString());
                response =IGtpushHttpClient.receiveMsg(client);
                client.disconnect();

                respData =(Map<String,Object>)IfspFastJsonUtil.jsonTOmap(response);
                if ("ok".equals(respData.get("result"))){
                    return respData;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

运行时需要引入个推的jar包,maven 引入时需要先将jar包上传到服务器中,然后在maven配置文件中。我是用的版本jra包是:

至于详细的文档可以参考官方提供的文档,地址:http://docs.getui.com/getui/server/java/start/

使用个推的时候如果不使用代理的话可以直接使用下载的文件中test工程中的代码,集成jra包后,可以参考单推,群推,直接使用。如果使用代理的话就需要重新写http链接。

个推的单推接口调用没有频次的限制,群推pushToList 接口调用是有频次限制的,就是每天调用200万次,每次发给用户数量建议50,pushToapp 每天不超过100次,每分钟不能超过5次。

使用官方提供的接口时:

每次初始化IGtPush这个类的时候都会去个推平台查询那些可用的推送地址。

然后推送消息的时候,步骤就如我画的流程图一样了,只不过单推pushTosigle 时没有获取TaskId这一步。

---------------二更---------------------------

由于我是使用的服务端,不区分安卓和ios所以使用的消息模板NotificationTemplate(通知)不能够满足要求(这个模板如果添加了iOS带码的话,就不能推送安卓了)所以要将消息模板换成TransmissionTemplate(透传)这个模板,然后在模板中设置三方通知。具体的代码如下:

package com.ruim.ifsp.merser.util;

import com.gexin.rp.sdk.base.impl.*;
import com.gexin.rp.sdk.base.notify.Notify;
import com.gexin.rp.sdk.base.payload.APNPayload;
import com.gexin.rp.sdk.base.uitls.Base64Util;
import com.gexin.rp.sdk.base.uitls.LangUtil;
import com.gexin.rp.sdk.base.uitls.SignUtil;
import com.gexin.rp.sdk.dto.GtReq;
import com.gexin.rp.sdk.http.utils.GTConfig;
import com.gexin.rp.sdk.http.utils.ParamUtils;
import com.gexin.rp.sdk.template.TransmissionTemplate;
import com.ruim.ifsp.exception.BizException;
import com.ruim.ifsp.log.IfspLoggerFactory;
import com.ruim.ifsp.merser.cache.CommonConstants;
import com.ruim.ifsp.utils.message.IfspFastJsonUtil;
import org.slf4j.Logger;

import java.net.HttpURLConnection;
import java.util.*;

public class IGtpushThread extends Thread {

    private static Logger log = IfspLoggerFactory.getLogger(IGtpushThread.class);

    private static String appId = CommonConstants.getProperties("IGTAPP_ID");
    private static String appKey = CommonConstants.getProperties("IGTAPP_KEY");
    private static String masterSecret = CommonConstants.getProperties("IGTMASTER_SECRET");
    private static String host = CommonConstants.getProperties("IGTPUST_HOST");

    private String alias;
    private String message;
    private String msgSendType;

    public IGtpushThread(String alias,String message,String msgSendType) {
        this.alias = alias;
        this.message = message;
        this.msgSendType = msgSendType;
    }
    /**
     * If this thread was constructed using a separate
     * <code>Runnable</code> run object, then that
     * <code>Runnable</code> object's <code>run</code> method is called;
     * otherwise, this method does nothing and returns.
     * <p>
     * Subclasses of <code>Thread</code> should override this method.
     *
     * @see #start()
     * @see #stop()
     * @see #(ThreadGroup, Runnable, String)
     */
    @Override
    public void run() {
        IGTpushMsg(alias,message,msgSendType);
    }
    public void IGTpushMsg(String alias,String message,String msgSendType){

        String respMsg = new String();
        String[] arr = alias.split(",");
        // 通知透传模板 消息传递
        TransmissionTemplate template = notificationTemplateDemo(message);
        ListMessage messages = new ListMessage();
        messages.setData(template);
        // 设置消息离线,并设置离线时间
        messages.setOffline(true);
        // 离线有效时间,单位为毫秒,可选
        messages.setOfflineExpireTime(24 * 1000 * 3600);
        // 配置推送目标
        List targets = new ArrayList();
        // taskId用于在推送时去查找对应的message
        try{
            String taskId = getListAppContentId(messages,null);
            Map<String,Object> postData = null;
            for (int i = 0; i < arr.length; i++) {
                Target target = new Target();
                target.setAppId(appId);
                target.setAlias(arr[i]);
                targets.add(target);
                //每50个别名(CID)推送一次
                if (arr.length>50&&targets.size()==50){
                    postData =pushMessageToList(taskId,targets);
                    Map<String,Object> response = httpResponse(postData);
                    if (!"ok".equals(response.get("result"))){
                        response = httpResponse(postData);
                        respMsg = IfspFastJsonUtil.mapTOjson(response);
                        log.info("个推建议值推送结果是:"+respMsg);
                    }
                    targets.clear();
                }
            }
            if (targets.size()>0){
                postData =pushMessageToList(taskId,targets);
                Map<String,Object> response = httpResponse(postData);
                if (!"ok".equals(response.get("result"))){
                    response = httpResponse(postData);
                    respMsg = IfspFastJsonUtil.mapTOjson(response);
                    log.info("个推第二次推送结果是:"+respMsg);
                }
            }
        }catch (Exception e){
            log.error("个推推送失败,原因是:"+e.getMessage());
        }
    }
    public Map<String, Object> pushMessageToList(String contentId, List<Target> targetList) throws Exception{
        Map<String, Object> postData = new HashMap();
        postData.put("authToken", null);
        postData.put("action", "pushMessageToListAction");
        postData.put("appkey", appKey);
        postData.put("contentId", contentId);
        boolean needDetails = GTConfig.isPushListNeedDetails();
        postData.put("needDetails", needDetails);
        boolean async = GTConfig.isPushListAsync();
        postData.put("async", async);
        boolean needAliasDetails = GTConfig.isPushListNeedAliasDetails();
        postData.put("needAliasDetails", needAliasDetails);
        int limit;
        if (async && !needDetails) {
            limit = GTConfig.getAsyncListLimit();
        } else {
            limit = GTConfig.getSyncListLimit();
        }
        if (targetList.size() > limit) {
            throw new BizException("1000","target size:" + targetList.size() + " beyond the limit:" + limit);
        } else {
            List<String> clientIdList = new ArrayList();
            List<String> aliasList = new ArrayList();
            String appId = null;
            Iterator var12 = targetList.iterator();

            while(true) {
                Target target;
                do {
                    if (!var12.hasNext()) {
                        postData.put("appId", appId);
                        postData.put("clientIdList", clientIdList);
                        postData.put("aliasList", aliasList);
                        postData.put("type", 2);
                        return postData;
                    }

                    target = (Target)var12.next();
                    String targetCid = target.getClientId();
                    String targetAlias = target.getAlias();
                    if (targetCid != null && !"".equals(targetCid.trim())) {
                        clientIdList.add(targetCid);
                    } else if (targetAlias != null && !"".equals(targetAlias.trim())) {
                        aliasList.add(targetAlias);
                    }
                } while(appId != null && !"".equals(appId.trim()));

                appId = target.getAppId();
            }
        }
    }
    public TransmissionTemplate notificationTemplateDemo(String message) {
//        NotificationTemplate template = new NotificationTemplate();
//        // 设置APPID与APPKEY
//        template.setAppId(appId);
//        template.setAppkey(appKey);
//        // 设置通知栏标题与内容
//        template.setTitle("黔农E付收款通知");
//        template.setText(message);
//        // 配置通知栏图标
//        template.setLogo("icon.png");
        // 配置通知栏网络图标
//        template.setLogoUrl("");
        // 设置通知是否响铃,震动,或者可清除
//        template.setIsRing(true);
//        template.setIsVibrate(true);
//        template.setIsClearable(true);
        // 透传消息设置,1为强制启动应用,客户端接收到消息后就会立即启动应用;2为等待应用启动
//        template.setTransmissionType(2);
//        template.setTransmissionContent(message);
        //ios 消息推送
//        APNPayload apnPayload = new APNPayload();
//        APNPayload.SimpleAlertMsg alertMsg = new APNPayload.SimpleAlertMsg(message);
//        apnPayload.setAlertMsg(alertMsg);
//        template.setAPNInfo(apnPayload);
//        return template;
        TransmissionTemplate template = new TransmissionTemplate();
        template.setAppId(appId);
        template.setAppkey(appKey);
        //设置透传消息
        template.setTransmissionContent(message);
        template.setTransmissionType(2);
        //设置三方通知
        Notify no = new Notify();
        no.setTitle("黔农E付收款通知!");
        no.setContent(message);
        no.setIntent(""); //客户端生成提供给服务端
        no.setType(GtReq.NotifyInfo.Type._intent);
        template.set3rdNotifyInfo(no);
        //设置ios推送消息
        APNPayload payload = new APNPayload();
        payload.setBadge(1);
        payload.setContentAvailable(1);
        payload.setSound("default");
        payload.setCategory("$由客户端定义");
        //简单模式APNPayload.SimpleMsg
        payload.setAlertMsg(new APNPayload.SimpleAlertMsg(message));
        //字典模式使用下者
        //payload.setAlertMsg(getDictionaryAlertMsg());
        template.setAPNInfo(payload);
        return template;
    }
    private String getListAppContentId(Message message, String taskGroupName) {
        Map<String, Object> postData = new HashMap();
        Map<String, Object> response = null;
        if (taskGroupName != null) {
            postData.put("taskGroupName", taskGroupName);
        }
        postData.put("action", "getContentIdAction");
        postData.put("appkey", appKey);
        postData.put("clientData", Base64Util.getBASE64(message.getData().getTransparent().toByteArray()));
        postData.put("transmissionContent", message.getData().getTransmissionContent());
        postData.put("isOffline", message.isOffline());
        postData.put("offlineExpireTime", message.getOfflineExpireTime());
        postData.put("pushType", message.getData().getPushType());
        postData.put("type", 2);
        if (message instanceof ListMessage) {
            postData.put("contentType", 1);
        } else if (message instanceof AppMessage) {
            postData.put("contentType", 2);
            AppMessage appMessage = (AppMessage) message;
            ParamUtils.checkAppid(message, appMessage.getAppIdList());
            postData.put("appIdList", appMessage.getAppIdList());
            List<String> phoneTypeList = null;
            List<String> provinceList = null;
            List<String> tagList = null;
            new ArrayList();
            if (appMessage.getConditions() == null) {
                phoneTypeList = appMessage.getPhoneTypeList();
                provinceList = appMessage.getProvinceList();
                tagList = appMessage.getTagList();
                postData.put("phoneTypeList", phoneTypeList);
                postData.put("provinceList", provinceList);
                postData.put("tagList", tagList);
            } else {
                List<Map<String, Object>> conditions = appMessage.getConditions().getCondition();
            }

            postData.put("speed", appMessage.getSpeed());
            String pushTime = appMessage.getPushTime();
            if (pushTime != null && !pushTime.isEmpty()) {
                postData.put("pushTime", pushTime);
            }
        }
        postData.put("pushNetWorkType", message.getPushNetWorkType());
        //调用个推 获取绑定的个推平台信息绑定的id
        response = httpResponse(postData);
        String result = LangUtil.parseString(response.get("result"));
        String contentId = LangUtil.parseString(response.get("contentId"));
        if ("ok".equals(result) && contentId != null) {
            return contentId;
        } else {
            throw new RuntimeException("host:[" + host + "]获取contentId失败:" + result);
        }
    }

    /**
     * http 调用方法
     * @param postData
     * @return
     */
    public Map<String,Object> httpResponse(Map<String,Object> postData){

        HttpURLConnection client = null;
        String response = null;
        try {
            postData.put("version", GTConfig.getSDKVersion());
            postData.put("authToken",null);
            client = IGtpushHttpClient.buildConnect(postData.get("action").toString());
            IGtpushHttpClient.sendMsg(client, IfspFastJsonUtil.mapTOjson(postData).toString());
            response =IGtpushHttpClient.receiveMsg(client);
            client.disconnect();
            Map<String,Object> respData =(Map<String,Object>)IfspFastJsonUtil.jsonTOmap(response);
            if ("ok".equals(respData.get("result"))){
                return respData;
            }
            if("sign_error".equals(respData.get("result"))){
                long timeStamp = System.currentTimeMillis();
                String sign = SignUtil.getSign(appKey, masterSecret, timeStamp);
                Map<String, Object> postData1 = new HashMap();
                postData1.put("action", "connect");
                postData1.put("appkey", appKey);
                postData1.put("timeStamp", timeStamp);
                postData1.put("sign", sign);
                postData1.put("version", GTConfig.getSDKVersion());
                client = IGtpushHttpClient.buildConnect(postData1.get("action").toString());
                IGtpushHttpClient.sendMsg(client, IfspFastJsonUtil.mapTOjson(postData1).toString());
                response =IGtpushHttpClient.receiveMsg(client);
                client.disconnect();

                Map<String,Object> respdata =(Map<String,Object>)IfspFastJsonUtil.jsonTOmap(response);
                //放入authToken 值
                postData.put("authToken",respdata.get("authtoken"));

                client = IGtpushHttpClient.buildConnect(postData.get("action").toString());
                IGtpushHttpClient.sendMsg(client, IfspFastJsonUtil.mapTOjson(postData).toString());
                response =IGtpushHttpClient.receiveMsg(client);
                client.disconnect();

                respData =(Map<String,Object>)IfspFastJsonUtil.jsonTOmap(response);
                if ("ok".equals(respData.get("result"))){
                    return respData;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    //苹果消息弹出框
    private static APNPayload.DictionaryAlertMsg getDictionaryAlertMsg(){
        APNPayload.DictionaryAlertMsg alertMsg = new APNPayload.DictionaryAlertMsg();
        alertMsg.setBody("body");
        alertMsg.setActionLocKey("ActionLockey");
        alertMsg.setLocKey("LocKey");
        alertMsg.addLocArg("loc-args");
        alertMsg.setLaunchImage("launch-image");
        // IOS8.2以上版本支持
        alertMsg.setTitle("Title");
        alertMsg.setTitleLocKey("TitleLocKey");
        alertMsg.addTitleLocArg("TitleLocArg");
        return alertMsg;
    }
}

透传模板集成到通知中官方提供文档:

1. 概述

  解决接入第三方推送遇到的兼容问题,降低接入成本。

2. 功能名字

2.1应用场景

  为方便接入了第三方厂商推送的客户,更加简便的使用个推透传模板推送,特别对透传模板进行扩展,使透传模板支持以第三方厂商的通知方式进行下发。目前第三方厂商的通知到达率显著高于第三方透传的到达率。

3. 使用方式

3.1使用说明

  使用透传模板时,设置notify对象的title, content, intent等参数。

Notify的说明

成员和方法名

类型

必填

说明

setTitle

String

通知栏标题

setContent

String

通知栏内容

setUrl

String

点击通知,打开应用的链接

setIntent

String

长度小于1000字节,通知带intent传递参数推荐使用,intent最好由Android开发工程师生成,生成方式见附录

setType

Type

取值为(Type._url、Type._intent),如果设置了url、intent,需要指定Type对应的类型;Type所在的包为:com.gexin.rp.sdk.dto.GtReq.NotifyInfo

 

 

 

 

 

 

public static TransmissionTemplate transmissionTemplateDemo(String appId, String appKey){

  TransmissionTemplate template = new TransmissionTemplate();

  template.setAppId(appId);

  template.setAppkey(appKey);

  template.setTransmissionContent("透传内容");

  template.setTransmissionType(2);

  Notify notify = new Notify();

  notify.setTitle("请输入通知栏标题");

  notify.setContent("请输入通知栏内容");

notify.setIntent("intent:#Intent;launchFlags=0x10000000;package=com.pp.yl;component=你的包名

/com.getui.demo.MainActivity;i.parm1=12;end");

notify.setType(Type._intent);

// notify.setUrl("https://dev.getui.com/");

//notify.setType(Type._url);

  template.set3rdNotifyInfo(notify);//设置第三方通知

  return template;

 }

 

4. 功能代码示例

 

 

 

5. 附录:Andriod开发工程师生成intent参考

  Andriod开发工程师生成intent,可以在Android代码中定义一个Intent,然后通过Intent.toUri(Intent.URI_INTENT_SCHEME)获取对应的Intent Uri。

 

Intent intent = new Intent();

 

5.1生成Intent

 

 

5.2设置 package(可选)

  如果设置了package,则表示目标应用必须是package所对应的应用。

 

intent.setPackage("com.getui.demo");

 

 

 

5.3设置 component (必选)

  component为目标页面的准确activity路径,component中包含应用包名和activity类的全路径。

 

intent.setComponent(new ComponentName("com.getui.demo", "com.getui.demo.TestActivity"));

 

 

 

5.4设置 launchFlags (不起作用)

  launcherFlags 可指定在启动activity时的启动方式,个推sdk以及厂商sdk在启动activity时会自动设置为FLAG_ACTIVITY_NEW_TASK,所以该设置没有实际意义。

5.5设置参数

 

intent.putExtra("stringType", "string");

intent.putExtra("booleanType", true);

intent.putExtra("doubleType", 1.0);

intent.putExtra("floatType", 1.0f);

intent.putExtra("longType", 1L);

intent.putExtra("intType", 1);

// 还有其他类型的参数可以设置,通过查找`putExtra`方法的重载方法即可

  可通过intent.putExtra方法设置一系列的参数。

 

 

 

 

 

5.6设置action

 

//设置action

intent.setAction("android.intent.action.oppopush");

  由于oppo sdk仅支持通过action的方式打开activity,所以若您的应用需要支持oppo推送(打开指定页面),您需要在intent中设置action,并在AndroidManifet.xml配置对应的action,如下:

 

 

 

 

<!-- android:exported="true" 必须配置,否则在华为机型上无法启动-->

<activity android:name="com.getui.demo.TestActivity"

         android:exported="true">

    <intent-filter>

    <!-- category 为必须设置项 设置为 android.intent.category.DEFAULT 即可-->

    <category android:name="android.intent.category.DEFAULT" />

    <action android:name="android.intent.action.oppopush" />

     </intent-filter>

 </activity>

AndroidManifet.xml配置如下:

 

 

 

 

 

 

 

 

 

5.7生成 intent uri

 

Log.d(TAG, intent.toUri(Intent.URI_INTENT_SCHEME));

 

 

 

打印结果为:intent:#Intent;action=android.intent.action.oppopush;package=com.getui.demo;component=com.getui.demo/com.getui.demo.TestActivity;f.floatType=1.0;l.longType=1;B.booleanType=true;S.stringType=string;d.doubleType=1.0;i.intType=1;end

将生成的intent uri交给服务端开发人员,在对应模板的setIntent方法中设置即可。

 

=====================三更====================================

使用jmeter测试,发现每次访问个推平台消耗时间大概是300毫秒左右,发送一次推送如果走完所有的流程,需要大概2500毫秒,很耗时间。而且,目前在生产上有用户反馈收不到推送信息,经过排查得知当日的推送消息次数超过了200万次,而多推pushListMessage有这个次数限制。所以需要优化这个推送流程。经过询问个推的开发人员得知,在交互的过程中获取鉴权码,鉴权码的有效期是24个小时,另外接口pushSingleMessage推送是没有次数限制。本次优化的流程思路就是将鉴权码保存到redis中,并设置有效期,推送接口使用单推+多推相结合的方式行优化。目前从测试结果来开个推使用还是有些问题。问题一:个推使用多推时离线发送(只有ios,所谓离线就是退出app页面,个推离线推送的时候会将消息推送给厂商,厂商将消息推送到设备,这个时间不可控,测试环境中,有时间延时,个推厂商给解释说开发环境苹果厂商推送不稳定)会有1~2分钟的时延。问题二:个推使用单推的时候,ios手机推出app,收不到推送消息,个推开发人员解释是开发环境苹果厂商aoip 推送不稳。鉴于这两种给推送结果,目前占时开发出两套优化流程 1. 单推+多推(生产上测试,测试没有问题,优先使用这个),2.多推 (1不行才采用这个方)

优化后代码流程:

1.单推:

2.多推:

优化后代码:

/**
     *@author lxw
     *@date 2019/12/20
     *@desc  安卓群推
     *@param alias, message, msgSendType
     *@return void
    **/
    public void IGTandroidPushMsg(String alias,String message){
        log.info("安卓用户{}开始推送日志.....",alias);
        String respMsg = new String();
        String[] arr = alias.split(",");
        // 通知透传模板 消息传递
        NotificationTemplate nTemplate = notificationTemplateDemo(message);
        ListMessage messages = new ListMessage();
        messages.setData(nTemplate);
        // 设置消息离线,并设置离线时间
        messages.setOffline(true);
        // 离线有效时间,单位为毫秒,可选
        messages.setOfflineExpireTime(24 * 1000 * 3600);
        // 配置推送目标
        List targets = new ArrayList();
        // taskId用于在推送时去查找对应的message
        try{
            String taskId = getListAppContentId(messages,null);
            Map<String,Object> postData = null;
            for (int i = 0; i < arr.length; i++) {
                Target target = new Target();
                target.setAppId(appId);
                target.setAlias(arr[i]);
                targets.add(target);
                //每50个别名(CID)推送一次
                if (arr.length>50&&targets.size()==50){
                    postData =pushMessageToList(taskId,targets);
                    Map<String,Object> response = httpResponse(postData);
                    if (!IGParams.PUSH_MSG_OK.equals(response.get("result"))){
                        response = httpResponse(postData);
                        respMsg = IfspFastJsonUtil.mapTOjson(response);
                    }
                    targets.clear();
                }
            }
            if (targets.size()>0) {
                postData = pushMessageToList(taskId, targets);
                Map<String, Object> response = httpResponse(postData);
                if (IGParams.PUSH_NO_TARGET.equals(response.get("result"))||IGParams.PUSH_MSG_OK.equals(response.get("result"))) {
                    log.info("用户{}个推推送结果是:" + response.get("result"),alias);
                }else {
                    response = httpResponse(postData);
                    respMsg = IfspFastJsonUtil.mapTOjson(response);
                    log.info("用户{}个推第二次推送结果是:" + respMsg,alias);
                }
            }
        }catch (Exception e){
            log.error("安卓用户{}推送失败,原因是:"+e.getMessage(),alias);
        }
    }
    /**
     *@author lxw
     *@date 2019/12/20
     *@desc 苹果群推
     *@param alias, message, msgSendType
     *@return void
    **/
    public void IGTIosPushMsg(String alias,String message){
        log.info("ios用户{}开始推送.....",alias);
        String respMsg = new String();
        String[] arr = alias.split(",");
        //透传模板 消息传递
        TransmissionTemplate tTemplate = transmissionTemplateDemo(message);
        ListMessage messages = new ListMessage();
        messages.setData(tTemplate);
        // 设置消息离线,并设置离线时间
        messages.setOffline(true);
        // 离线有效时间,单位为毫秒,可选
        messages.setOfflineExpireTime(24 * 1000 * 3600);
        // 配置推送目标
        List targets = new ArrayList();
        // taskId用于在推送时去查找对应的message
        try{
            String taskId = getListAppContentId(messages,null);
            Map<String,Object> postData = null;
            for (int i = 0; i < arr.length; i++) {
                Target target = new Target();
                target.setAppId(appId);
                target.setAlias(arr[i]);
                targets.add(target);
                //每50个别名(CID)推送一次
                if (arr.length>50&&targets.size()==50){
                    postData =pushMessageToList(taskId,targets);
                    Map<String,Object> response = httpResponse(postData);
                    if (!IGParams.PUSH_MSG_OK.equals(response.get("result"))){
                        response = httpResponse(postData);
                        respMsg = IfspFastJsonUtil.mapTOjson(response);
                    }
                    targets.clear();
                }
            }
            if (targets.size()>0){
                postData =pushMessageToList(taskId,targets);
                Map<String,Object> response = httpResponse(postData);
                if (IGParams.PUSH_NO_TARGET.equals(response.get("result"))||IGParams.PUSH_MSG_OK.equals(response.get("result"))) {
                    log.info("用户{}个推推送结果是:" + response.get("result"),alias);
                }else {
                    response = httpResponse(postData);
                    respMsg = IfspFastJsonUtil.mapTOjson(response);
                    log.info("用户{}再次推送结果是:" + response.get("result"),alias);
                }
            }
        }catch (Exception e){
            log.error("ios用户{}推送失败,原因是:"+e.getMessage(),alias);
        }
    }
    /**
     *@author lxw
     *@date 2019/12/20
     *@desc 群推消息参数组装
     *@param contentId, targetList
     *@return java.util.Map<java.lang.String,java.lang.Object>
    **/
    public Map<String, Object> pushMessageToList(String contentId, List<Target> targetList) throws Exception{
        log.info("pushMessageToList组装推送参数开始,用户taskid:{}。。。。",contentId);
        Map<String, Object> postData = new HashMap();
        postData.put("authToken", getAuthTokenCache().opsForValue().get("authToken")==null?"":getAuthTokenCache().opsForValue().get("authToken"));
        postData.put("action", "pushMessageToListAction");
        postData.put("appkey", appKey);
        postData.put("contentId", contentId);
        boolean needDetails = GTConfig.isPushListNeedDetails();
        postData.put("needDetails", needDetails);
        boolean async = GTConfig.isPushListAsync();
        postData.put("async", async);
        boolean needAliasDetails = GTConfig.isPushListNeedAliasDetails();
        postData.put("needAliasDetails", needAliasDetails);
        int limit;
        if (async && !needDetails) {
            limit = GTConfig.getAsyncListLimit();
        } else {
            limit = GTConfig.getSyncListLimit();
        }
        if (targetList.size() > limit) {
            throw new BizException("1000","target size:" + targetList.size() + " beyond the limit:" + limit);
        } else {
            List<String> clientIdList = new ArrayList();
            List<String> aliasList = new ArrayList();
            String appId = null;
            Iterator var12 = targetList.iterator();

            while(true) {
                Target target;
                do {
                    if (!var12.hasNext()) {
                        postData.put("appId", appId);
                        postData.put("clientIdList", clientIdList);
                        postData.put("aliasList", aliasList);
                        postData.put("type", 2);
                        return postData;
                    }

                    target = (Target)var12.next();
                    String targetCid = target.getClientId();
                    String targetAlias = target.getAlias();
                    if (targetCid != null && !"".equals(targetCid.trim())) {
                        clientIdList.add(targetCid);
                    } else if (targetAlias != null && !"".equals(targetAlias.trim())) {
                        aliasList.add(targetAlias);
                    }
                } while(appId != null && !"".equals(appId.trim()));

                appId = target.getAppId();
            }
        }
    }
    //通知消息
    public NotificationTemplate notificationTemplateDemo(String message) {
        NotificationTemplate template = new NotificationTemplate();
        // 设置APPID与APPKEY
        template.setAppId(appId);
        template.setAppkey(appKey);
        Style0 style = new Style0();
        style.setTitle("黔农E付收款通知");
        // 设置通知栏标题与内容
        style.setText(message);
        // 配置通知栏网络图标
        style.setLogo("icon.png");
        // 设置通知是否响铃,震动,或者可清除
        style.setRing(true);
        style.setVibrate(true);
        style.setClearable(true);
        // 透传消息设置,1为强制启动应用,客户端接收到消息后就会立即启动应用;2为等待应用启动
        template.setTransmissionType(1);
        template.setTransmissionContent(message);
        template.setStyle(style);
        return template;
    }
    //透传消息
    public TransmissionTemplate transmissionTemplateDemo(String message) {
        Map<String,String> msgMap = new HashMap<>();
        msgMap.put("黔农商户宝",message);
        TransmissionTemplate template = new TransmissionTemplate();
        template.setAppId(appId);
        template.setAppkey(appKey);
        //透传消息设置
        template.setTransmissionContent(IfspFastJsonUtil.mapTOjson(msgMap));
        template.setTransmissionType(2);
        //ios 消息推送
        APNPayload payload = new APNPayload();
        payload.setAutoBadge("1");
        payload.setContentAvailable(0);
        payload.setVoicePlayType(1);
        payload.setSound("default");
        payload.setCategory("$由客户端定义");
        VoIPPayload voIPPayload = new VoIPPayload();
        Map<String,Object> vp = new HashMap<>();
        vp.put("titile","黔农E付收款通知");
        vp.put("message",message);
        vp.put("payload","payload");
        voIPPayload.setVoIPPayload(IfspFastJsonUtil.mapTOjson(vp));
        template.setAPNInfo(voIPPayload);
        return template;
    }
    //获取群推的taskid
    private String getListAppContentId(Message message, String taskGroupName) {
        Map<String, Object> postData = new HashMap();
        Map<String, Object> response = null;
        if (taskGroupName != null) {
            postData.put("taskGroupName", taskGroupName);
        }
        postData.put("action", "getContentIdAction");
        postData.put("appkey", appKey);
        postData.put("clientData", Base64Util.getBASE64(message.getData().getTransparent().toByteArray()));
        postData.put("transmissionContent", message.getData().getTransmissionContent());
        postData.put("isOffline", message.isOffline());
        postData.put("offlineExpireTime", message.getOfflineExpireTime());
        postData.put("pushType", message.getData().getPushType());
        postData.put("type", 2);
        if (message instanceof ListMessage) {
            postData.put("contentType", 1);
        } else if (message instanceof AppMessage) {
            postData.put("contentType", 2);
            AppMessage appMessage = (AppMessage) message;
            ParamUtils.checkAppid(message, appMessage.getAppIdList());
            postData.put("appIdList", appMessage.getAppIdList());
            List<String> phoneTypeList = null;
            List<String> provinceList = null;
            List<String> tagList = null;
            new ArrayList();
            if (appMessage.getConditions() == null) {
                phoneTypeList = appMessage.getPhoneTypeList();
                provinceList = appMessage.getProvinceList();
                tagList = appMessage.getTagList();
                postData.put("phoneTypeList", phoneTypeList);
                postData.put("provinceList", provinceList);
                postData.put("tagList", tagList);
            } else {
                List<Map<String, Object>> conditions = appMessage.getConditions().getCondition();
            }

            postData.put("speed", appMessage.getSpeed());
            String pushTime = appMessage.getPushTime();
            if (pushTime != null && !pushTime.isEmpty()) {
                postData.put("pushTime", pushTime);
            }
        }
        postData.put("pushNetWorkType", message.getPushNetWorkType());
        //调用个推 获取绑定的个推平台信息绑定的id
        response = httpResponse(postData);
        String result = LangUtil.parseString(response.get("result"));
        String contentId = LangUtil.parseString(response.get("contentId"));
        if (IGParams.PUSH_MSG_OK.equals(result) && contentId != null) {
            return contentId;
        } else {
            throw new RuntimeException("host:[" + host + "]获取contentId失败:" + result);
        }
    }
    /**
     * http 调用方法
     * @param postData
     * @return
     */
    public Map<String,Object> httpResponse(Map<String,Object> postData){
        log.info("调用平台传参:"+IfspFastJsonUtil.mapTOjson(postData));
        HttpURLConnection client = null;
        String response = null;
        Map<String,Object> respData = new HashMap<>();
        try {
            postData.put("version", GTConfig.getSDKVersion());
            postData.put("authToken",getAuthTokenCache().opsForValue().get("authToken")==null?"":getAuthTokenCache().opsForValue().get("authToken"));
            client = IGtpushHttpClient.buildConnect(postData.get("action").toString());
            IGtpushHttpClient.sendMsg(client, IfspFastJsonUtil.mapTOjson(postData).toString());
            response =IGtpushHttpClient.receiveMsg(client);
            client.disconnect();
            respData =(Map<String,Object>)IfspFastJsonUtil.jsonTOmap(response);

            if(IGParams.PUSH_SIGN_ERROR.equals(respData.get("result"))){
                long timeStamp = System.currentTimeMillis();
                String sign = SignUtil.getSign(appKey, masterSecret, timeStamp);
                Map<String, Object> postData1 = new HashMap();
                postData1.put("action", "connect");
                postData1.put("appkey", appKey);
                postData1.put("timeStamp", timeStamp);
                postData1.put("sign", sign);
                postData1.put("version", GTConfig.getSDKVersion());
                client = IGtpushHttpClient.buildConnect(postData1.get("action").toString());
                IGtpushHttpClient.sendMsg(client, IfspFastJsonUtil.mapTOjson(postData1).toString());
                response =IGtpushHttpClient.receiveMsg(client);
                client.disconnect();
                Map<String,Object> respdata =(Map<String,Object>)IfspFastJsonUtil.jsonTOmap(response);
                //放入authToken 值

                postData.put("authToken",respdata.get("authtoken"));
                //将authToken 放入redis 并设置超时时间
                getAuthTokenCache().opsForValue().set("authToken",(String)respdata.get("authtoken"),TimeUnit.HOURS.toHours(24),TimeUnit.HOURS);
                client = IGtpushHttpClient.buildConnect(postData.get("action").toString());
                IGtpushHttpClient.sendMsg(client, IfspFastJsonUtil.mapTOjson(postData).toString());
                response =IGtpushHttpClient.receiveMsg(client);
                client.disconnect();
                respData =(Map<String,Object>)IfspFastJsonUtil.jsonTOmap(response);
                return respData;
            }
            return respData;
        } catch (Exception e) {
            log.error("个推接收响应信息失败,原因是:"+e.getMessage());
        }
        return respData;
    }
    //苹果消息弹出框
    private static APNPayload.DictionaryAlertMsg getDictionaryAlertMsg(String message){
        APNPayload.DictionaryAlertMsg alertMsg = new APNPayload.DictionaryAlertMsg();
        alertMsg.setBody(message);
        alertMsg.setTitle("黔农E付收款通知");
        return alertMsg;
    }
    /**
     *@author lxw
     *@date 2019/12/20
     *@desc 单推消息参数组装
     *@param message, target, requestId
     *@return java.util.Map<java.lang.String,java.lang.Object>
    **/
    public Map<String, Object> pushMessageToSingle(Message message, Target target, String requestId) {

        HttpURLConnection client = null;
        String  response = new String();
        if (requestId == null || "".equals(requestId.trim())) {
            requestId = UUID.randomUUID().toString();
        }
        Map<String, Object> pushResult = new HashMap<>();
        ParamUtils.checkAppid(message, target);
        Map<String, Object> postData = this.getSingleMessagePostData(message, target, requestId);
        try {
            pushResult = httpResponse(postData);
        }catch (Exception e){
            log.error("单推失败!"+e.getMessage());
        }
        return pushResult;
    }
    /**
     *@author lxw
     *@date 2019/12/20
     *@desc 单推上送消息组装
     *@param message, target, requestId
     *@return java.util.Map<java.lang.String,java.lang.Object>
    **/
    Map<String, Object> getSingleMessagePostData(Message message, Target target, String requestId) {
        Map<String, Object> postData = new HashMap();
        postData.put("action", "pushMessageToSingleAction");
        postData.put("appkey", this.appKey);
        if (requestId != null) {
            postData.put("requestId", requestId);
        }
        postData.put("clientData", Base64Util.getBASE64(message.getData().getTransparent().toByteArray()));
        postData.put("transmissionContent", message.getData().getTransmissionContent());
        postData.put("isOffline", message.isOffline());
        postData.put("offlineExpireTime", message.getOfflineExpireTime());
        postData.put("appId", target.getAppId());
        postData.put("clientId", target.getClientId());
        postData.put("alias", target.getAlias());
        postData.put("type", 2);
        postData.put("pushType", message.getData().getPushType());
        postData.put("pushNetWorkType", message.getPushNetWorkType());
        return postData;
    }
    /**
     *@author lxw
     *@date 2019/12/20
     *@desc 安卓单推
     *@param alias, message, msgSendType
     *@return void
    **/
    public void iGSinglePust(String alias,String message) {
        log.info("安卓用户{}开始推送。。。",alias);
        NotificationTemplate template = notificationTemplateDemo(message);
        SingleMessage messages = new SingleMessage();
        messages.setOffline(true);
        // 离线有效时间,单位为毫秒,可选
        messages.setOfflineExpireTime(24 * 3600 * 1000);
        messages.setData(template);
        // 可选,1为wifi,0为不限制网络环境。根据手机处于的网络情况,决定是否下发
        messages.setPushNetWorkType(0);
        Target target = new Target();
        target.setAppId(appId);
        target.setAlias(alias);
        Map<String, Object> ret = null;
        try {
            ret = pushMessageToSingle(messages, target,null);
        } catch (RequestException e) {
            log.error("服务器响应异常:"+e.getMessage());
            ret = pushMessageToSingle(messages, target, e.getRequestId());
        }
    }
    /**
     *@author lxw
     *@date 2019/12/20
     *@desc ios单推
     *@param alias, message, msgSendType
     *@return void
    **/
    public void iGSinglePustIOS(String alias,String message) {
        log.error("苹果用户{}开始推送",alias);
        TransmissionTemplate template =  transmissionTemplateDemo(message);
        SingleMessage messages = new SingleMessage();
        messages.setOffline(true);
        // 离线有效时间,单位为毫秒,可选
        messages.setOfflineExpireTime(24 * 3600 * 1000);
        messages.setData(template);
        // 可选,1为wifi,0为不限制网络环境。根据手机处于的网络情况,决定是否下发
        messages.setPushNetWorkType(0);
        Target target = new Target();
        target.setAppId(appId);
        target.setAlias(alias);
        Map<String, Object> ret = null;
        try {
            ret = pushMessageToSingle(messages, target,null);
        } catch (RequestException e) {
            log.error("服务器响应异常:"+e.getMessage());
            ret = pushMessageToSingle(messages, target, e.getRequestId());
        }
    }

    //获取spring中redis 注册的bean
    public IfspRedisCacheOperation<String> getPushRedisCacheOperation(){
        return (IfspRedisCacheOperation<String>) IfspSpringContextUtils.getInstance().getBean("pushRedisCache");
    }
    public IfspRedisCacheOperation<String> getAuthTokenCache(){
        return (IfspRedisCacheOperation<String>) IfspSpringContextUtils.getInstance().getBean("authTokenRedisCache");
    }

http 链接还是使用最上方的链接

工具类:

public Static final String PUSH_SIGN_ERROR="sign_error";
public Static final String PUSH_NO_TARGET="NOTarget";
public Static final String PUSH_MSG_OK="ok";

总结:

1.目前生产使用模式是单推+多推结合的方式。

2.个推推送分为 离线推送、在线推送,在线推送是指 个推平台将消息推送给手机,离线推送是指 个推将消息推送给手机厂商,由厂商来推送消息。区分是离线推送还是在线推送,可以查看推送成功后的响应报文中有个推送状态,那里会显示是离线推送还是在线推送。

3.手机接收不到消息问题排查

    3.1:核对配置参数是否正确(appId,appKey,masterScript.....);

    3.2:如果是使用别名推送,查看推送是否绑定了cid(个推为每个手机设备分配的识别码,每个手机只能生成一个,不会变);个推平台提供了方法查询别名下绑定的cid 个数,每个别名只能绑定10个cid。别名绑定超过10时候,新绑定的cid 会将已经绑定的cid其中一个顶掉。别名下cid 查询:

import com.gexin.rp.sdk.base.IAliasResult;
import com.gexin.rp.sdk.http.IGtPush;

public class GETTUIaLIAS {

    private static String appId = "QFoBXS1TrJ9yc";//个推上配置的appId
    private static String appKey = "M2FJjXxnP3Ark";//个推上配置的appKey 
    private static String masterSecret = "aWU9lqy8CX6EP";//个推上配置的masterSecret 
    static String host = "http://sdk.open.api.igexin.com/apiex.htm";




    public static void main(String[] args) {
        String Alias = "8201807060000001_13641064684";//要查询的别名
        IGtPush push = new IGtPush(host, appKey, masterSecret);
        IAliasResult queryClient = push.queryClientId(appId, Alias);
        System.out.println("根据别名获取的CID:" + queryClient.getClientIdList());
    }
}

,服务端是获取不到每个手机的cid ,需要客户端(app端) 来获取cid。查看cid 所属苹果或者安卓可以去个推平台

中,输入别名下查询出cid ,就可以查看出手机型号和所属手机厂商。