生产者消费者模式个推

package com.sunline.sysconf.thread;

 

import java.util.ArrayList;

import java.util.Date;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import java.util.Map.Entry;

import java.util.concurrent.BlockingQueue;

 

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

 

import com.sunline.common.config.DefaultConfig;

import com.sunline.persist.po.DeviceInfo;

import com.sunline.persist.po.MsgSendRecord;

import com.sunline.sysconf.dao.DeviceInfoDao;

import com.sunline.sysconf.util.AppMsgUtil;

import com.sunline.sysconf.util.ConstantsConf;

import com.sunline.sysconf.vo.PushAppBean;

 

/**

 * 消息消费线程

 * @author David

 *

 */

public class MsgConsumerThread implements Runnable{

private static Logger log = LoggerFactory.getLogger(MsgConsumerThread.class);

private volatile boolean  isRunning= true;

private DefaultConfig defaultConfig;

private DeviceInfoDao deviceInfoDao;

private BlockingQueue<PushAppBean> queue;

public MsgConsumerThread(BlockingQueue<PushAppBean> queue,DeviceInfoDao deviceInfoDao,DefaultConfig defaultConfig) {

        this.queue = queue;

        this.deviceInfoDao=deviceInfoDao;

        this.defaultConfig=defaultConfig;

    }

@Override

public void run() {

String sAppId=defaultConfig.getVal("app.appId");

String sAppKey=defaultConfig.getVal("app.appkey");

String sAppHost=defaultConfig.getVal("app.host");

String sAppMaster=defaultConfig.getVal("app.master");

        try {

            while (isRunning) {

            log.info("MsgConsumerThread start!"); 

            PushAppBean  pushBean = queue.poll();

                if (null != pushBean) {

  log.info("queue poll msgId:"+pushBean.getMsgId()+",queue size:"+queue.size());

                   //查询所有设备

                   List<DeviceInfo> deviceInfoList=deviceInfoDao.findDeviceTokenAll(pushBean.getDeptId());

                   int size=deviceInfoList.size();

                   if(size>0){

                  Map<String,List<String>> deviceMap=new HashMap<String,List<String>>();

                  for(DeviceInfo device:deviceInfoList){

                  String deviceType=device.getDeviceType();

                  List<String> deviceTokenList=deviceMap.get(deviceType);

                  if(null==deviceTokenList){

                  deviceTokenList=new ArrayList<String>();

                  deviceMap.put(deviceType, deviceTokenList);

                  }

                  deviceTokenList.add(device.getDeviceToken());

                  }

                  int num=deviceMap.size();

                  int record=0;

                  for(Entry<String,List<String>> entry:deviceMap.entrySet()){

                  //0 安卓系统 1 IOS系统 

                  String key=entry.getKey();

                  List<String> tokenIds=entry.getValue();

                  int type="ios".equals(key)?1:0;

                  String code=AppMsgUtil.pushMessage(sAppId, sAppKey, sAppHost, sAppMaster,pushBean, type, tokenIds);

                  log.info("send code:"+code);

                  record+=Integer.parseInt(code);

                  }

                       if(record==num){

                      MsgSendRecord sendRecord=new MsgSendRecord();

                      sendRecord.setMsgId(pushBean.getMsgId());

                      sendRecord.setCreateTime(new Date());

                      deviceInfoDao.saveMsgSendRecord(sendRecord);

                       }

                   }

                }

                Thread.sleep(ConstantsConf.THREAD_SLEEP);

                log.info("MsgConsumerThread end!"); 

            }

        } catch (Exception ce) {

            ce.printStackTrace();

            log.error("Consumer msg error",ce);

        }

}

 

}

 

 

package com.sunline.sysconf.thread;

 

import java.util.List;

import java.util.concurrent.BlockingQueue;

 

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

 

import com.sunline.sysconf.dao.DeviceInfoDao;

import com.sunline.sysconf.util.ConstantsConf;

import com.sunline.sysconf.vo.MsgInfoResVo;

import com.sunline.sysconf.vo.PushAppBean;

 

/**

 * 消息生产线程

 * @author David

 *

 */

public class MsgProducerThread implements Runnable{

 

private static Logger log = LoggerFactory.getLogger(MsgProducerThread.class);

 

private BlockingQueue<PushAppBean> queue;

 

private volatile boolean  isRunning= true;

 

private DeviceInfoDao deviceInfoDao;

 

public MsgProducerThread(BlockingQueue<PushAppBean> queue,DeviceInfoDao deviceInfoDao){

this.queue = queue;

this.deviceInfoDao=deviceInfoDao;

}

 

@Override

public void run() {

try {

  while (isRunning) {

  log.info("MsgProducerThread start!"); 

  //查询需要发送的消息列表

  List<MsgInfoResVo> msgList=deviceInfoDao.findMsgInfo();

  int size=msgList.size();

  if(size>0){

 for(MsgInfoResVo msgVo:msgList){

  PushAppBean appBean=new PushAppBean();

  appBean.setTitle(msgVo.getMsgTitle());

  appBean.setContent(msgVo.getMsgContent());

  appBean.setMsgType(msgVo.getMsgType());

  appBean.setMsgTime(msgVo.getMsgTime());

  appBean.setMsgId(msgVo.getMsgId());

  appBean.setDeptId(msgVo.getDeptId());

  queue.offer(appBean);

  log.info("queue offer msgId:"+msgVo.getMsgId()+",queue size:"+queue.size());

  }

 Thread.sleep((size+2)*ConstantsConf.THREAD_SLEEP);

  }else{

 Thread.sleep(ConstantsConf.THREAD_SLEEP);

  }

  log.info("MsgProducerThread end!"); 

}

} catch (Exception ce) {

  log.error("Producer msg error",ce); 

  ce.printStackTrace();

}

}

 

public void stop() {

        isRunning = false;

    }

 

}

 

package com.sunline.sysconf.util;

 

import java.util.ArrayList;

import java.util.List;

 

import org.apache.commons.lang.StringUtils;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

 

import com.alibaba.fastjson.JSONObject;

import com.gexin.rp.sdk.base.IPushResult;

import com.gexin.rp.sdk.base.impl.ListMessage;

import com.gexin.rp.sdk.base.impl.Target;

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

import com.gexin.rp.sdk.template.TransmissionTemplate;

import com.sunline.sysconf.vo.PushAppBean;

import com.sunline.sysconf.vo.PushBean;

 

package com.sunline.sysconf.util;

 

import java.util.ArrayList;

import java.util.List;

 

import org.apache.commons.lang.StringUtils;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

 

import com.alibaba.fastjson.JSONObject;

import com.gexin.rp.sdk.base.IPushResult;

import com.gexin.rp.sdk.base.impl.ListMessage;

import com.gexin.rp.sdk.base.impl.Target;

import com.gexin.rp.sdk.base.payload.APNPayload;

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

import com.gexin.rp.sdk.template.TransmissionTemplate;

import com.sunline.sysconf.vo.PushAppBean;

import com.sunline.sysconf.vo.PushBean;

 

public class AppMsgUtil {

private static Logger log = LoggerFactory.getLogger(AppMsgUtil.class);

/**

* 推送方法 

* @param sAppId

* @param sAppKey

* @param sAppHost

* @param sAppMaster

* @param pushBean

* @param osType

* @param tokenIds 0 安卓系统 1 IOS系统 

* @return

*/

public static String pushMessage(String sAppId, String sAppKey,String sAppHost, String sAppMaster,PushAppBean pushBean,int osType,List<String> tokenIds){

String code="";

try{

 String msgContext=pushBean.getContent();

 String msgTitle=pushBean.getTitle();

 String msgType=pushBean.getMsgType();

 String msgTime=pushBean.getMsgTime();

 //个推参数连接设置

 IGtPush push = new IGtPush(sAppHost, sAppKey, sAppMaster);

 //创建连接

 push.connect();

 //多个设备列表信息推送对象

 ListMessage listMessage = new ListMessage();

 //设备列表

 List<Target> lstTargets = new ArrayList<Target>();

 //透传消息模板

 TransmissionTemplate emp=null;

 if(0==osType){

 emp=transmissionTemplate(sAppId, sAppKey, msgContext,msgTitle,msgType,msgTime);

 }else{

 emp=iosTransmissionTemplate(sAppId, sAppKey, msgTitle, msgContext, msgType, msgTime);

 }

 for (String sTokenId : tokenIds) {

Target target = new Target();

target.setAppId(sAppId);

target.setClientId(sTokenId);

lstTargets.add(target);

 }

 //透传消息模板

 listMessage.setData(emp);

 //设置消息离线,并设置离线时间

 listMessage.setOffline(true);

     //离线有效时间,单位为毫秒,可选

 listMessage.setOfflineExpireTime(24 * 1000 * 3600);

 // 计算taskId

 String taskId = push.getContentId(listMessage);

 //发送并获取返回的结果对象

 IPushResult ret = push.pushMessageToList(taskId, lstTargets);

 //结果返回

 String result = ret.getResponse().get("result").toString().trim();

 if (!StringUtils.isBlank(result)) {

result = result.trim();

log.info("push app result:"+result);

if (result.equalsIgnoreCase("ok")) {

code="1";

log.info("推送成功,taskId:" + taskId);

} else {

code="0";

log.info("推送失败,个推返回结果:" + result + ", taskId:" + taskId);

}

}

}catch(Exception ce){

ce.printStackTrace();

log.error("push app error",ce);

code="0";

}

   return code;

}

/**

* 透传消息模板设置

* @param sAppId  应用id

* @param sAppKey 应用密钥

* @param context 透传消息

* @param mobileType 设备类型

* @return 透传消息模板对象

*/

public static TransmissionTemplate transmissionTemplate(String sAppId, String sAppKey,String msgContext,String msgTitle,String msgType,String msgTime) {

// 透传消息模板对象

TransmissionTemplate transmissionTemplate = new TransmissionTemplate();

transmissionTemplate.setAppId(sAppId);

transmissionTemplate.setAppkey(sAppKey);

//收到消息是否立即启动应用,1为立即启动,2则广播等待客户端自启动

transmissionTemplate.setTransmissionType(2);

//应是组装后的JSON字符串

PushBean push=new PushBean();

push.setTitle(msgTitle);

if(StringUtils.isNotBlank(msgContext) && msgContext.length() > 400) {

msgContext=msgContext.replaceAll("\\s*", "").substring(0, 400) + "...";

}

push.setContent(msgContext);

push.setMsgType(msgType);

push.setMsgTime(msgTime);

String json=JSONObject.toJSONString(push);

transmissionTemplate.setTransmissionContent(json);

// 返回透传模板对象

return transmissionTemplate;

}

  

/**

* IOS的强提醒消息模板

* @param transmissionTemplate

* @param sAppId

* @param sAppKey

* @param msgTitle

* @param msgContext

* @param msgType

* @param msgTime

* @return

*/

public static TransmissionTemplate iosTransmissionTemplate(String sAppId, String sAppKey,String msgTitle, String msgContext, String msgType,String msgTime) {

// 透传消息模板对象

TransmissionTemplate transmissionTemplate = new TransmissionTemplate();

transmissionTemplate.setAppId(sAppId);

transmissionTemplate.setAppkey(sAppKey);

//收到消息是否立即启动应用,1为立即启动,2则广播等待客户端自启动

transmissionTemplate.setTransmissionType(2); 

//应是组装后的JSON字符串

PushBean push=new PushBean();

push.setTitle(msgTitle);

if(StringUtils.isNotBlank(msgContext) && msgContext.length() > 400) {

msgContext=msgContext.replaceAll("\\s*", "").substring(0, 400) + "...";

}

push.setContent(msgContext);

push.setMsgType(msgType);

push.setMsgTime(msgTime);

String json=JSONObject.toJSONString(push);

//应是组装后的JSON字符串

transmissionTemplate.setTransmissionContent(json); 

APNPayload payload = new APNPayload();

payload.setBadge(1);

   payload.setContentAvailable(1);

   payload.setSound("default");

   //payload.setCategory("$由客户端定义"); 

   //简单模式APNPayload.SimpleMsg 

   payload.setAlertMsg(new APNPayload.SimpleAlertMsg(msgContext));

   transmissionTemplate.setAPNInfo(payload);

return transmissionTemplate; 

}

 

}

 

启动线程的主类

public class SunlineCfgServer {

 

private static Logger logger = Logger.getLogger(SunlineCfgServer.class);

 

public static void main(String[] args) {

 

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

logger.info("Spring container of UserHttpServer init finished...");

DefaultConfig defaultConfig = (DefaultConfig) ctx.getBean("defaultConfig");

DeviceInfoDao deviceInfoDao = (DeviceInfoDao) ctx.getBean("deviceInfoDaoImpl");

BlockingQueue<PushAppBean> queue = new LinkedBlockingQueue<PushAppBean>(ConstantsConf.QUE_LEN);

MsgProducerThread msgProducer = new MsgProducerThread(queue,deviceInfoDao);

MsgConsumerThread msgConsumer=new MsgConsumerThread(queue,deviceInfoDao,defaultConfig);

// 借助Executors

 ExecutorService service = Executors.newCachedThreadPool();

 // 启动线程

 service.execute(msgProducer);

service.execute(msgConsumer);

}

}

猜你喜欢

转载自taiwei-peng.iteye.com/blog/2360838