定時羣發主要分爲兩部分:定時任務和羣發任務java
定時任務能夠經過前臺傳遞過來的時間參數,來啓動定時器,並在指定的時間,啓動羣發任務。json
定時任務設置代碼以下服務器
/** * 在某個時間點執行一次 * @Title SimpleRun * @Description * @author Administrator * @param * @return void * @throws ParseException */ private void SimpleRun(Record record) { //獲取到前臺傳遞過來的時間參數 String send_time = record.getStr("send_time"); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); SchedulerFactory factory = new StdSchedulerFactory(); Scheduler schedule; Date send_date = null; int time = 0; try { send_date = sdf.parse(send_time); //獲取任務調度器 schedule = factory.getScheduler(); //此對象用來像job傳遞參數 JobDataMap dataMap = new JobDataMap(); dataMap.put("msg_record", record); //定義job對象,並綁定自定義WXArticleSendJob類 //真正執行job的任務,並非實現了Job接口的WXArticleSendJob類,而是經過反射的方式實例化的一個JobDetail的對象 JobDetail jobDetail = JobBuilder.newJob(WXArticleSendJob.class).withIdentity(send_time, Constants.WX_GROUP).usingJobData(dataMap).build(); // Date start_time = DateBuilder.nextGivenSecondDate(null, 10); SimpleTrigger simpleTrigger = (SimpleTrigger) TriggerBuilder.newTrigger(). withIdentity("simpleTrigger", "wx_trigger_group").withDescription("定時羣發微信") /* .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(10)//重複間隔 .withRepeatCount(5))//重複次數 */ .startAt(send_date).build(); Date df = schedule.scheduleJob(jobDetail, simpleTrigger); log.info("job id 爲"+jobDetail.getKey().getName()+ "的任務,將在"+sdf.format(df)+"運行. 而且基於描述: "+simpleTrigger.getDescription()); MsgSendService service = new MsgSendService(); //羣發信息入庫 boolean flag = service.saveMsg(record); schedule.start(); } catch (SchedulerException e) { time++; System.out.println("time --------"+time); e.printStackTrace(); } catch (ParseException e) { e.printStackTrace(); log.error(e.getMessage()); } } /** * 定時羣發job * 此job的主要功能是向粉絲髮送消息 * 因爲微信服務器將會在羣發任務即將完成的時候,就推送羣髮結果,此時的推送人數數據將會與實際情形存在必定偏差 * @author Administrator * * 2015-12-10 */ @DisallowConcurrentExecution//保存在JobDataMap傳遞的參數 @PersistJobDataAfterExecution//保證多個任務間不會同時執行.因此在多任務執行時最好加上 public class WXArticleSendJob implements Job{ public static final Logger log = Logger.getLogger(WXArticleSendJob.class); @Override public void execute(JobExecutionContext context) { JobDataMap dataMap = context.getJobDetail().getJobDataMap(); Record msg_record = (Record) dataMap.get("msg_record"); //token String token = AccessTokenApi.getAccessToken().getAccessToken(); String data = processSendMsgData(msg_record); JSONObject jsonObj = null; int count = 0; //像微信服務器發送羣發任務,最多嘗試三次 while(count < Constants.TOTAL_COUNT){ //羣發 String result = HttpKit.post(Constants.SEND_MSG+token, data); //解析羣髮結果 jsonObj = JSONObject.parseObject(result); int errcode = jsonObj.getIntValue("errcode"); //說明報錯了 if(0 != errcode){ count++; log.error(jsonObj.getString("errmsg")); }else{ break; } } //說明沒有請求成功 if(count == Constants.TOTAL_COUNT){ msg_record.set("errmsg", jsonObj.getString("errmsg")); msg_record.set("type", 2); }else{ String msg_id = jsonObj.getString("msg_id"); String msg_data_id = jsonObj.getString("msg_data_id"); msg_record.set("msg_id", msg_id); msg_record.set("msg_data_id", msg_data_id); } MsgSendService service = new MsgSendService(); //羣發信息入庫 try { service.updateMsg(msg_record); } catch (ParseException e) { e.printStackTrace(); log.error(e.getMessage()); } // 任務執行的時間 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy 年 MM 月 dd 日 HH 時 mm 分 ss 秒"); String jobRunTime = dateFormat.format(Calendar.getInstance().getTime()); String jobName = context.getJobDetail().getKey().getName(); log.info("任務"+jobName+"在"+jobRunTime+"執行了"); } /** * * @Title processSendMsgData * @Description 拼接羣發須要的字符串 * @author Administrator * @param * @date 2016-1-27 * @return String */ private String processSendMsgData(Record record){ String msg_type = record.getStr("msg_type"); StringBuffer sb = new StringBuffer("{"); if("news".equalsIgnoreCase(msg_type)){ sb.append("\"filter\":").append("{").append("\"is_to_all\":").append(record.getInt("is_to_all")).append(",\"group_id\":").append(record.getInt("group_id")).append("},"); sb.append("\"mpnews\":").append("{").append("\"media_id\":\"").append(record.getStr("media_id")).append("\"").append("},"); sb.append("\"msgtype\":").append("\"mpnews\""); }else if("voice".equalsIgnoreCase(msg_type)){ sb.append("\"filter\":").append("{").append("\"is_to_all\":").append(record.getInt("is_to_all")).append(",\"group_id\":").append(record.getInt("group_id")).append("},"); sb.append("\"voice\":").append("{").append("\"media_id\":\"").append(record.getStr("media_id")).append("\"").append("},"); sb.append("\"msgtype\":").append("\"voice\""); }else if("text".equalsIgnoreCase(msg_type)){ sb.append("\"filter\":").append("{").append("\"is_to_all\":").append(record.getInt("is_to_all")).append(",\"group_id\":").append(record.getInt("group_id")).append("},"); sb.append("\"text\":").append("{").append("\"content\":\"").append(record.getStr("content")).append("\"").append("},"); sb.append("\"msgtype\":").append("\"text\""); }else if("image".equalsIgnoreCase(msg_type)){ sb.append("\"filter\":").append("{").append("\"is_to_all\":").append(record.getInt("is_to_all")).append(",\"group_id\":").append(record.getInt("group_id")).append("},"); sb.append("\"image\":").append("{").append("\"media_id\":\"").append(record.getStr("media_id")).append("\"").append("},"); sb.append("\"msgtype\":").append("\"image\""); }else if("video".equalsIgnoreCase(msg_type)){ } sb.append("}"); return sb.toString(); }