package com.smp.sev.sms;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.smp.bean.MsgSubmit;
import com.smp.sev.cache.OperatorInfo;
import com.smp.sev.service.MsgService;
import com.smp.util.MsgUtil;
import com.smp.util.SmpProperty;
import com.smp.util.Tools;
/**
* @author xml
*
*/
@Service
public class MsgSender {
@Autowired
private MsgService ms;
@Autowired
private OperatorInfo op;
private static final Logger logger = Logger.getLogger(MsgSender.class);
private Timer msgTimer = new Timer("msgTimer");
public MsgSender() {
setSno(SmpProperty.getInstance().getStartSno(), SmpProperty.getInstance().getEndSno());
}
/**
* 短信服务器请求地址
*/
private static int msgid = 0;
/**
* 当前的短号
*/
private int curShortNo = 0;
/**
* 短号的开始号码--字符串形式,方便上行时匹配
*/
private static String STARTSHORTNO_STR = "0";
/**
* 短号的开始号码-
*/
private int STARTSHORTNO = 0;
/**
* 短号的结束号码
*/
private int ENDSHORTNO = 0;
private synchronized int getShortNo() {
if(curShortNo==0) {
curShortNo = ms.getMaxShortNo();
}
if(curShortNo<STARTSHORTNO||curShortNo>=ENDSHORTNO)curShortNo=STARTSHORTNO+10;
curShortNo++;
return curShortNo;
}
public synchronized int getMsgid() {
if(msgid==0) {
msgid = ms.getMaxMsgid();
if(msgid==-1)msgid = 0;
}
msgid++;
return msgid;
}
public void setSno(int startSno, int endSno) {
STARTSHORTNO = startSno;
STARTSHORTNO_STR = String.valueOf(startSno);
ENDSHORTNO = endSno;
}
public static String getStartSno() {
return STARTSHORTNO_STR;
}
public MsgSubmit setIdAndShortNo(MsgSubmit ms) {
ms.setMsId(getMsgid());
if("选项调查".equals(ms.getMsType())){
ms.setMsShortno(String.valueOf(getShortNo()));
}else ms.setMsShortno(STARTSHORTNO_STR);
return ms;
}
private void send(final MsgSubmit msg, final List<String[]> users, String phones, final boolean isSaveLog,final boolean issavemsg){
if(msg==null||users==null||(users!=null&&users.size()==0)) {
return;
}
//判断手机号是那个运营商,分别调用不同的网关
Map<String, String> operator=op.getHeNanYiDong();
final StringBuffer yidong=new StringBuffer();
final StringBuffer other=new StringBuffer();
for(String[] u:users){
String phone=u[1];
if(phone!=null&&phone.length()>6){
if(operator.containsKey(phone.substring(0, 7))){
yidong.append(phone+",");
}else{
other.append(phone+",");
}
}
}
if(yidong.length()>0){
yidong.deleteCharAt(yidong.length()-1);
}
if(other.length()>0){
other.deleteCharAt(other.length()-1);
}
System.out.println(yidong.length()+":"+other.length());
new Thread(new Runnable(){
public void run() {
long spendtime = 0;
if (logger.isDebugEnabled()) {
spendtime = System.currentTimeMillis();
logger.debug("$MsgSenderRunnable.run() - start");
}
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(SmpProperty.getInstance().getSendMessageUrl());
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
if("立即发送".equals(msg.getMsTimer())) {
msg.setMsSendtime(new Timestamp(System.currentTimeMillis()));
}
String state = "发送成功";
try {
if(other.length()>0){
//其它网关发送
//添加签名【掌上校园】
String sMsg = msg.getMsContent()+MsgUtil.QM_YYS;
httpclient = new DefaultHttpClient();
nvps.add(new BasicNameValuePair("id",SmpProperty.getInstance().getSendMessageId()));
nvps.add(new BasicNameValuePair("MD5_td_code",SmpProperty.getInstance().getSendMessageMD5_td_code()));
nvps.add(new BasicNameValuePair("mesg_id",String.valueOf(msg.getMsId())));
nvps.add(new BasicNameValuePair("mobile",other.toString()));
nvps.add(new BasicNameValuePair("msg_content", sMsg));
if(Tools.isNotEmpty(msg.getMsShortno()))
nvps.add(new BasicNameValuePair("extend", msg.getMsShortno()));
httppost = new HttpPost(SmpProperty.getInstance().getSendMessageUrl());
httppost.setEntity(new UrlEncodedFormEntity(nvps, "GBK"));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
String entitys = EntityUtils.toString(entity, "GBK");
// String entitys = "ok:3";
if (logger.isDebugEnabled()) {
logger.debug("entitys:"+entitys);
}
entitys = entitys.toLowerCase();
int okIndex = entitys.indexOf("ok:");
if(okIndex==-1){
if(logger.isInfoEnabled())
logger.info("其它:发送失败,状态码"+entitys+"用户数"+other.toString().split(",").length+":"+sMsg);
state = "发送失败";
}
if(logger.isInfoEnabled()) {
if(okIndex!=-1) {
logger.info("其它:发送消息成功,用户数:"+other.toString().split(",").length+":"+sMsg);
state="发送成功";
}
}
}else if(yidong.length()>0){
}
}
catch (UnsupportedEncodingException e) {
logger.error("UnsupportedEncodingException", e);
state = "发送失败";
}
catch (ClientProtocolException e) {
logger.error("ClientProtocolException", e);
state = "发送失败";
}
catch (IOException e) {
logger.error("IOException", e);
state = "发送失败";
}
if(yidong.length()>0){
try {
//移动 网关发送
nvps = new ArrayList <NameValuePair>();
nvps.add(new BasicNameValuePair("msgid",String.valueOf(msg.getMsId())));
nvps.add(new BasicNameValuePair("phone",yidong.toString()));
nvps.add(new BasicNameValuePair("msg", msg.getMsContent()));
if("长短信".equals(msg.getMsLongmsg())) {
nvps.add(new BasicNameValuePair("longmsg","1"));
}else {
nvps.add(new BasicNameValuePair("longmsg","0"));
}
if(Tools.isNotEmpty(msg.getMsShortno()))
nvps.add(new BasicNameValuePair("sno", msg.getMsShortno()));
httppost = new HttpPost(SmpProperty.getInstance().getYidong());
httppost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
String entitys = EntityUtils.toString(entity, "UTF-8");
// String entitys = "0";
if("0".equals(entitys)){
logger.info("移动:发送消息成功,用户数:"+yidong.toString().split(",").length+":"+msg.getMsContent());
state="发送成功"; //标记发送状态
if("回执确认".equals(msg.getMsType())) state = "接收回执";
}else if("-1".equals(entitys)){
logger.info("移动:发送消息失败,用户数"+yidong.toString().split(",").length+":"+msg.getMsContent());
state = "发送失败";
}else {
logger.info("移动:短信服务器返回未知状态:<"+entitys+"> 用户数:"+yidong.toString().split(",").length+":"+msg.getMsContent());
state = "未知状态";
}
}catch (UnsupportedEncodingException e) {
logger.error("UnsupportedEncodingException", e);
state = "发送失败";
}
catch (ClientProtocolException e) {
logger.error("ClientProtocolException", e);
state = "发送失败";
}
catch (IOException e) {
logger.error("IOException", e);
state = "发送失败";
}
}
msg.setMsState(state);
if("定时发送".equals(msg.getMsTimer())) {
ms.updateSubmitState(msgid, state,true,true,true); //更新信息发送状态,包括信息详细 每条状态
}
if(isSaveLog)ms.addSubmit(msg, users,issavemsg);
if (logger.isDebugEnabled()) {
spendtime = System.currentTimeMillis()-spendtime;
logger.debug("$MsgSenderRunnable.run() - end spendtime:"+spendtime);
}
}
}).start();
}
/**发送短信通知,短信内容不能超过500字
* @param users 用户手机号和uid的集合,不能为空
* @param msgSubmit 发送的短信内容,不能为空。如果为普通短信msSendtime和msSendtime不用填写
*/
public void sendMsg(MsgSubmit msg, List<String[]> users,String sendtype) {
List<String[]> vUser = new ArrayList<String[]>();
StringBuffer phones = new StringBuffer();
for(String[] user: users) {
if(user.length!=2) {
String[] eru = {user[0],"","手机号为空"};
vUser.add(eru);
}else {
String pho = user[1];
if(Tools.isEmpty(pho)||pho.length()!=11) {
String[] eru = {user[0],user[1],"手机号格式错误"};
vUser.add(eru);
}else {
//检查运营商
//加入发送号码
phones.append(",").append(user[1]);
vUser.add(user);
}
}
}
//去除第一个手机号前的逗号
if(phones.length()>0)phones.deleteCharAt(0);
if(phones.length()==0) {
msg.setMsState("发送失败");
ms.addSubmit(msg, vUser,true);
}else {
//超时后修改发送状态为 "调查结束"
if(msg.getMsOvertime()!=null) {
final OverMsgTask overTask = new OverMsgTask(msg, ms);
msgTimer.schedule(overTask, msg.getMsOvertime());
}
if("定时发送".equals(msg.getMsTimer())) {
msg.setMsState("未发送");
String ct = msg.getMsContent();
ms.addSubmit(msg, vUser,true);
msg.setMsContent(ct);
final SendMsgTask msgTask = new SendMsgTask(msg, vUser, phones.toString(), this);
msgTimer.schedule(msgTask , msg.getMsSendtime());
}else {
if("resend".equals(sendtype)){ //如果是重新发送,则不进行记录
sendLongMsg(msg, vUser, phones.toString(), false);
}else{
sendLongMsg(msg, vUser, phones.toString(), true);
}
}
}
}
public void sendMsgFromServer(MsgSubmit msg, List<String[]> users,String sendtype) {
List<String[]> vUser = new ArrayList<String[]>();
StringBuffer phones = new StringBuffer();
for(String[] user: users) {
if(user.length!=2) {
String[] eru = {user[0],"","手机号为空"};
vUser.add(eru);
}else {
String pho = user[1];
if(Tools.isEmpty(pho)||pho.length()!=11) {
String[] eru = {user[0],user[1],"手机号格式错误"};
vUser.add(eru);
}else {
//检查运营商
//加入发送号码
phones.append(",").append(user[1]);
vUser.add(user);
}
}
}
//去除第一个手机号前的逗号
if(phones.length()>0)phones.deleteCharAt(0);
if(phones.length()==0) {
msg.setMsState("发送失败");
ms.addSubmit(msg, vUser,true);
}else {
if("定时发送".equals(msg.getMsTimer())) {
final SendMsgTask msgTask = new SendMsgTask(msg, vUser, phones.toString(), this);
msgTimer.schedule(msgTask , msg.getMsSendtime());
}else {
if("resend".equals(sendtype)){ //如果是重新发送,则不进行记录
sendLongMsg(msg, vUser, phones.toString(), false);
}else{
sendLongMsg(msg, vUser, phones.toString(), true);
}
}
}
}
class SendMsgTask extends TimerTask {
private MsgSubmit msg;
private List<String[]> users;
String phones;
private MsgSender sender;
SendMsgTask(MsgSubmit msg, final List<String[]> users, String phones, MsgSender sender) {
this.msg = msg;
this.users = users;
this.sender = sender;
this.phones = phones;
}
@Override
public void run() {
this.sender.sendLongMsg(msg, users, phones, false);
}
}
class OverMsgTask extends TimerTask {
private MsgSubmit msg;
private MsgService ms;
OverMsgTask(MsgSubmit msg, MsgService ms) {
this.msg = msg;
this.ms = ms;
}
@Override
public void run() {
//修改MsgSubmit的state为调查结束
ms.updateSubmitState(msg.getMsId(), "调查结束");
}
}
private void sendLongMsg(MsgSubmit msg, List<String[]> users, String phones, boolean isSaveLog) {
//首先保存msg信息 然后发送信息,如果超过100条,则进行分隔100发送,
if("立即发送".equals(msg.getMsTimer())) {
msg.setMsSendtime(new Timestamp(System.currentTimeMillis()));
}
// if("定时发送".equals(msg.getMsTimer())) {
// ms.updateSubmitState(msgid, "发送成功");
// }
if(isSaveLog){
msg.setMsState("发送成功");
String ct = msg.getMsContent();
ms.addSub(msg);
msg.setMsContent(ct);
}
//百悟网关自动判断是否使用长短信发送, 字数不能超过500字
//判断人数是否超过100,如果超过100条则,分次数发完。
int count=users.size();
int maxsize=90;
if (count <= maxsize) {
logger.debug("第" + 1 + "次/共 1 次发送...");
System.out.println("第" + 1 + "次/共 1 次发送...");
send(msg, users, phones, isSaveLog,false);
} else {
for (int i = 0; i < count / maxsize; i++) {
logger.debug("第" + (i + 1) + "次发送...");
System.out.println("第" + (i + 1) + "次发送...");
List myusers=users.subList(i * maxsize, (i + 1) * maxsize);
logger.debug("用户数:"+myusers.size());
send(msg, myusers, phones, isSaveLog,false);
try {
Thread.sleep (500); //发送程序暂停1秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (count % maxsize != 0) {
logger.debug("第" + (count / maxsize + 1) + "次发送...");
System.out.println("第" + (count / maxsize + 1) + "次发送...");
List myusers=users.subList((count - count % maxsize), users.size());
logger.debug("用户数:"+myusers.size());
send(msg, myusers, phones, isSaveLog,false);
}
}
/*if(msg.getMsContent().length()<192) {
send(msg, users, isSaveLog);
}else {
//TODO 此处设计有问题,当字数多时,只要全部发送成功才算成功。
while(true) {
String message = msg.getMsContent();
if(message.length()>192) {
String str = message.substring(0, 192);
msg.setMsContent(str);
send(msg, users, isSaveLog);
message = message.substring(192);
}else {
send(msg, users, isSaveLog);
break;
}
}
}*/
}
}
分享到:
相关推荐
在IT行业中,短信发送模块是通信系统中的一个重要组成部分,它主要负责通过串行接口(Serial Port)发送短信。本文将详细讲解如何制作一个短信发送模块,包括串口短信的发送指令、格式、编解码类型以及参数设置等...
在泛微e-office V10.0版本中,设置短信发送功能需要通过泛微短信接口进行开发。下面将详细介绍泛微e-office短信插件的设置步骤和泛微短信接口的开发过程。 一、泛微e-office短信插件设置 泛微e-office短信插件是...
本主题主要探讨的是如何使用Java来实现SMGP协议进行短信发送,以及相关的开发资源。 首先,`zjtelecom-1.0.jar`是一个Java库文件,它包含了实现SMGP协议所需的各种类和方法。这个库可能包含了对SMGP报文构造、解析...
匿名短信发送源码,成本0.1一条65字源码限制了120字最大,卡密版本,可自己后台生成卡密 可自己对接代刷或者社区卖卡!表白祝福啥的 1.系统环境 -php要求 5.6 过高部分函数会失效无法使用 -mysql 无要求,数据库...
在本压缩包“实用的asp短信发送代码.rar”中,包含的是一个基于ASP的短信发送接口程序,适用于开发者集成到自己的Web系统中,以便实现短信通知、验证等功能。以下是对这个短信发送代码的知识点详细解释: 1. ASP...
在Unity3D游戏开发中,有时需要集成短信发送功能,以实现用户验证、通知推送等服务。"U3D调动短信发送功能"是指在Unity3D项目中集成并调用短信SDK来实现实时发送短信的功能。这个压缩包"SMSSDK-for-Unity3D-master...
本文将深入探讨“FastAdmin短信插件”、“FastAdmin短信接口开发”以及“FastAdmin短信发送设置”这三个核心知识点。 1. FastAdmin短信插件: FastAdmin的短信插件是用于实现系统与用户之间通过短信进行交互的重要...
【Android短信发送程序详解】 在Android开发中,创建一个简单的短信发送程序是常见的实践,尤其对于初学者来说,这是理解Android系统服务和权限管理的重要环节。这个程序的实现基于老师的指导,通过实际操作并测试...
阿里云和腾讯云短信发送服务是企业级应用中常见的通讯工具,主要用于验证码、通知消息以及营销推广等场景。本文将详细讲解如何使用C#语言在.NET 4.5框架下集成这两个云服务进行短信发送。 首先,我们需要了解阿里云...
在Android平台上,开发人员可以利用系统的短信服务API来实现发送短信以及监听短信发送的状态。这一功能对于构建一些需要确认信息传递的应用,如验证码发送、通知提醒等,是至关重要的。以下将详细介绍如何在Android...
而“中文短信免费发1.2”则表明有专门针对中文短信发送的软件版本。 在这个专题下,可以涵盖的知识点包括: 1. **免费短信服务的工作原理**:解释这些服务如何通过广告支持、合作推广或者其他商业模式来维持运营,...
在Android平台上,短信发送是移动应用开发中常见的一项功能,特别是在构建通信或通知类应用时。这个【Android】短信发送的示例(Demo)旨在帮助开发者理解如何在Android应用程序中集成短信发送的功能。通过分析提供...
【短信发送SDK包】是一种专为开发者设计的软件开发工具包,它允许应用程序轻松地集成短信发送功能。SDK(Software Development Kit)通常包含了一系列API(Application Programming Interface)、文档、示例代码、库...
该项目为Java语言编写的短信发送解决方案,采用CMPP、SGIP、SMGP、SMPP等多种短信协议进行封装,通过提供简单的HTTP接口,实现短信的快速发送。项目包含512个Java源文件,2个XML配置文件,以及1个Git忽略文件、1个...
当我们谈论"短信发送界面,非常漂亮的"时,这显然涉及到一个应用或系统中用于发送短信的功能模块,而且该模块在视觉设计上具有较高的美学价值。在C#编程语言中,我们可以利用.NET Framework或更现代的.NET Core平台...
Java 短信发送程序是一种基于Java编程语言开发的应用,用于向移动设备发送文本消息。在信息技术领域,这种程序常用于验证码验证、通知服务、营销推广等场景。本篇文章将详细探讨Java实现短信发送功能的核心技术和...
【短信发送Demo】是一个专为Android开发者设计的实践项目,旨在教授如何在Android实体设备上实现短信发送功能。这个Demo工程包含了一系列的代码示例和配置文件,帮助开发者理解和掌握Android系统中的短信发送机制。...
Java 实现短信发送 Java 实现短信发送是指利用 Java 语言编写程序来实现服务器向手机发送短信的过程。在这里,我们将使用 Java 语言来实现这个功能,并且使用了 Apache 的 Commons HttpClient 库来发送 HTTP 请求。...
在本文中,我们将深入探讨如何使用Node.js与阿里云短信服务接口进行集成,以便实现高效、可靠的短信发送功能。阿里云短信服务是一个强大的云通信平台,提供了多种API和SDK,帮助开发者快速构建短信发送功能。在Node....