短信发送


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;
}
}
}*/
}
}

潮汐研究作为海洋科学的关键分支,融合了物理海洋学、地理信息系统及水利工程等多领域知识。TMD2.05.zip是一套基于MATLAB环境开发的潮汐专用分析工具集,为科研人员与工程实践者提供系统化的潮汐建模与计算支持。该工具箱通过模块化设计实现了两大核心功能: 在交互界面设计方面,工具箱构建了图形化操作环境,有效降低了非专业用户的操作门槛。通过预设参数输入模块(涵盖地理坐标、时间序列、测站数据等),用户可自主配置模型运行条件。界面集成数据加载、参数调整、可视化呈现及流程控制等标准化组件,将复杂的数值运算过程转化为可交互的操作流程。 在潮汐预测模块中,工具箱整合了谐波分解法与潮流要素解析法等数学模型。这些算法能够解构潮汐观测数据,识别关键影响要素(包括K1、O1、M2等核心分潮),并生成不同时间尺度的潮汐预报。基于这些模型,研究者可精准推算特定海域的潮位变化周期与振幅特征,为海洋工程建设、港湾规划设计及海洋生态研究提供定量依据。 该工具集在实践中的应用方向包括: - **潮汐动力解析**:通过多站点观测数据比对,揭示区域主导潮汐成分的时空分布规律 - **数值模型构建**:基于历史观测序列建立潮汐动力学模型,实现潮汐现象的数字化重构与预测 - **工程影响量化**:在海岸开发项目中评估人工构筑物对自然潮汐节律的扰动效应 - **极端事件模拟**:建立风暴潮与天文潮耦合模型,提升海洋灾害预警的时空精度 工具箱以"TMD"为主程序包,内含完整的函数库与示例脚本。用户部署后可通过MATLAB平台调用相关模块,参照技术文档完成全流程操作。这套工具集将专业计算能力与人性化操作界面有机结合,形成了从数据输入到成果输出的完整研究链条,显著提升了潮汐研究的工程适用性与科研效率。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值