短信回复上行功能开发经验及具体开发实现

一、推送方式

用户通过如下地址设置url参数,以下蓝色部分为用户自定义参数,%XXX%固定。

用户提供接收上行的url,采用post方式推送
http://www.url.com/mo.aspx?args=%XXX%
      %XXX%格式如下:
mo ID,特服号,手机号,内容(对内容进行gb2312解码),时间,如有多条以英文“;”隔开,最多1000条
123456,62891,138****065,ceshi01,2009-10-19 15:51:05;123456,62891,139****404,test02,2009-10-19 15:51:17
返回:0接收成功,其它或异常返回
      注:moid 推送的时候是固定值(123456),因为这个参数没有太大的意义 您们在保存数据的时候这一参数可以忽略;如果您要保存请不要把它设成主键。

二、C++短信回复示例代码

 

	struct RECV_MSG //定义结构
{
	CString csRevevieID;
	CString csSendNum;
	CString csContent;
	CString csTime;
	CString csExCode;//特服号+扩展码组成的号码
};


1.获取并记录短信回复内容RecevieSMS()

	void CSendSMS_REPLY::RecevieSMS()//获取一次,然后内容插入数据库记录,用于更新显示
{
	CWebInterface  WebInterface (Pregister->szSerNO,Pregister->csPWD);	
	CArray< RECV_MSG,RECV_MSG&> caRevevieMSG;
	int iState=WebInterface.RecevieMSG(caRevevieMSG);//解码后的所有短信结构数组.

	if (WEBS_RET_FAIL==iState)
	{
		MessageBox(_T("没有需要接收的短信."),MESSAGE_INFO,MB_OK|MB_ICONWARNING);
		return;
	}		
	int iCount=caRevevieMSG.GetCount();
	if (0==iCount)
	{
		return;
	}
	CString csStartTime,csEndTime;//多条短信累计接收时候,记录第一条记录的时间和最后一条记录的时候。因为不知道接口返回结果记录的顺序,所以后面来判断取最小的
	CDatabase db;
	db.Open(NULL,false,false,theApp.strDsn,TRUE);
	db.GetConnect();
	for(int i=0;i<=iCount;i++)
	{
		RECV_MSG stOneMSG=caRevevieMSG.GetAt(i);
		char *pError=NULL;
		CString csSQL;
		COleDateTime  ctSendTime;
		ctSendTime.ParseDateTime(stOneMSG.csTime);
		stOneMSG.csTime=ctSendTime.Format(_T("%Y-%m-%d %H:%M:%S"));//格式化为:csTime
		stOneMSG.csContent.Replace(_T("'"),_T("''"));//CString csContent;
		int nSeReNum;
		CString csExNum= stOneMSG.csExCode.Right(stOneMSG.csExCode.GetLength()-Pregister->csCode.GetLength());//CString csExCode
		if (csExNum.IsEmpty())
		{
			nSeReNum=-1;
		}
		else
		{
			char *pExNum = UnicodeToANSI(csExNum);
			nSeReNum=atoi(pExNum);
			free(pExNum);
		}
		CString lianxiren;
		lianxiren=GetName(stOneMSG.csSendNum);//取得联系人名字
		db.ExecuteSQL(_T("insert into [RevevieMSG] (csRevevieID,lianxiren,csSendNum,csContent,csTime,csExCode) values ('"+stOneMSG.csRevevieID+"','"+lianxiren+"','"+stOneMSG.csSendNum+"','"+stOneMSG.csContent+"','"+stOneMSG.csTime+"','"+csExNum+"') "));
		if(0==i)
		{
			csStartTime = stOneMSG.csTime;
		}
		if (iCount-1 == i)
		{
			csEndTime = stOneMSG.csTime;
		}
	}
	db.Close();
	update_data(_T("select *  from [RevevieMSG] order by id desc"));
}


2.获取短信回复内容RecevieMSG(CArray< RECV_MSG,RECV_MSG&> &caRevevieMSG)

int CWebInterface::RecevieMSG(CArray< RECV_MSG,RECV_MSG&> &caRevevieMSG)
{
	_ns1__mo  param1;
	_ns1__moResponse  WebsResult;

	param1.sn = m_pSN;
	param1.pwd =m_pMd5;

	//WRITE_LOG_LW("call mo");
	SetTimeout(150);
	int nRet =m_WebService.__ns2__mo(¶m1,&WebsResult);

	if (nRet)
	{
		char szLog[128];
		sprintf(szLog,"Error,mo,nRet=%d",nRet);
		//g_LogRun.WriteLog(szLog);
		//::MessageBox(0,_T("网络错误."),CompanyInfo.csCompanyInfo,MB_OK|MB_ICONERROR);
		return WEBS_RET_FAIL;
	}
	int nSvrRet =atoi(WebsResult.moResult);//strtoul(WebsRet.mdSmsSendResult,0,10);
	if (nSvrRet>1)
	{
		int nLogBufLen = strlen(WebsResult.moResult)+128;
		char *pLogBuf =  new char[nLogBufLen];	
		sprintf(pLogBuf,"mo,webResult=%s",WebsResult.moResult);
		//g_LogRun.WriteLog(pLogBuf);
		delete [] pLogBuf;
	}
	if (1==nSvrRet || nSvrRet< 0)
	{
		return WEBS_RET_FAIL;

	}
	CString csRecevieContent;
	csRecevieContent=WebsResult.moResult;
	CStringArray csaRecevieContent;

	gSplit(csRecevieContent,csaRecevieContent,_T("\r\n"));//每条短信用回车换行隔开.	

	int iCount=csaRecevieContent.GetCount();
	for(int i=0;i< iCount;i++)
	{
		CString csOneMSG=csaRecevieContent.GetAt(i);

		CStringArray csaOneMSG;

		gSplit(csOneMSG,csaOneMSG,_T(","));//一条短信内各部分用","隔开.

		RECV_MSG stMSG;
		stMSG.csRevevieID=csaOneMSG.GetAt(0);//第二个元素为接收者的特服号
		stMSG.csExCode=csaOneMSG.GetAt(1);//特服号+扩展码组成的号串
		stMSG.csSendNum=csaOneMSG.GetAt(2);
		stMSG.csContent=csaOneMSG.GetAt(3);
		stMSG.csTime=csaOneMSG.GetAt(4);

		stMSG.csExCode.Replace(_T(","),_T(""));
		stMSG.csSendNum.Replace(_T(","),_T(""));
		stMSG.csContent.Replace(_T(","),_T(""));
		stMSG.csTime.Replace(_T(","),_T(""));

		char szTemp[1024]={0};
		char *pszTemp = UnicodeToANSI(stMSG.csContent);
		int nDecodeLen =UrlDecode(pszTemp,strlen(pszTemp));

		WCHAR *wpTemp=ANSIToUnicode(pszTemp);
		stMSG.csContent=wpTemp;	

		caRevevieMSG.Add(stMSG);
		free(pszTemp);
		free(wpTemp);
	}	

	char szLog[128];
	sprintf(szLog,"RecevieMSG 接收到%d条短信(解析后)。",caRevevieMSG.GetCount());
	return WEBS_RET_OK;
}


3.gSplit(CString &source, CStringArray& dest, CString division)

void CWebInterface::gSplit(CString &source, CStringArray& dest, CString division)
{
	dest.RemoveAll();
	int pos = 0;
	int pre_pos = 0;
	while( -1 != pos ){
		pre_pos = pos;
		pos = source.Find(division,(pos+1));
		if(-1==pos)
		{
			dest.Add(source.Mid(pre_pos,source.GetLength()));
			break;
		}
		dest.Add(source.Mid(pre_pos,(pos-pre_pos)));
	}	

}


4.UnicodeToANSI( const wchar_t *str )

char *  CWebInterface::UnicodeToANSI( const wchar_t *str )//直接用WideCharToMultiByte一次不支持中文
{
	char * result;
	int textlen;
	// wide char to multi char
	textlen = WideCharToMultiByte( CP_ACP,    0,    str,    -1,    NULL, 0, NULL, NULL );
	result =(char *)malloc((textlen+1)*sizeof(char));
	memset( result, 0, sizeof(char) * ( textlen + 1 ) );
	WideCharToMultiByte( CP_ACP, 0, str, -1, result, textlen, NULL, NULL );
	return result;
}


5.ANSIToUnicode( const char* str )

wchar_t * CWebInterface::ANSIToUnicode( const char* str ) 	//直接用MultiByteToWideChar一次不支持中文
{
	int    textlen ;
	wchar_t * result;
	textlen = MultiByteToWideChar( CP_ACP, 0, str,-1,    NULL,0 );  
	result = (wchar_t *)malloc((textlen+1)*sizeof(wchar_t));  
	memset(result,0,(textlen+1)*sizeof(wchar_t));  
	MultiByteToWideChar(CP_ACP, 0,str,-1,(LPWSTR)result,textlen );  
	return    result;  
}


6.UrlDecode(char *pScrBuf, int nLen)

int CWebInterface::UrlDecode(char *pScrBuf, int nLen)
{
	char *pDest = pScrBuf;
	char *pData = pScrBuf;

	int nValue;
	int nTemp;

	while (nLen--) {
		if (*pData == '+') {
			*pDest = ' ';
		}
		else if (*pData == '%' && nLen >= 2 && isxdigit((int) *(pData + 1))
			&& isxdigit((int) *(pData + 2)))
		{

			nTemp = ((unsigned char *)(pData+1))[0];
			if (isupper(nTemp))
				nTemp = tolower(nTemp);
			nValue = (nTemp >= '0' && nTemp <= '9' ? nTemp - '0' : nTemp - 'a' + 10) * 16;
			nTemp = ((unsigned char *)(pData+1))[1];
			if (isupper(nTemp))
				nTemp = tolower(nTemp);
			nValue += nTemp >= '0' && nTemp <= '9' ? nTemp - '0' : nTemp - 'a' + 10;

			*pDest = (char)nValue ;
			pData += 2;
			nLen -= 2;
		} else {
			*pDest = *pData;
		}
		pData++;
		pDest++;
	}
	*pDest = '\0';
	return pDest - pScrBuf;
}


 

三、C#短信回复示例代码

1.获取回复网页代码.htm

<form id="form_Receive" method="post" runat="server">
	<a  href="mo.aspx?args=67266896,132710,18636924700,%c4%c7%c4%e3%bf%b4%bd%f0%bb%c6%bd%f0%bb%c6%b5%c4,2015-6-6 18:50:31">推过去</a>
	</form>


2.获取回复网页代码mo.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="mo.aspx.cs" Inherits="mo" %>


3.获取回复实现mo.aspx.cs

 using System;
	using System.Collections.Generic;
	using System.Web;
	using System.Web.UI;
	using System.Web.UI.WebControls;
	using System.Text;
	using System.IO;

public partial class mo : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string content = Request["args"];
        if (content == null || content == "")
        {
            Response.Write("no data");
        }
        else {
            record(content);
            Response.Write("0");
        }
    }
    private void record(string data)
    {
        string[] temp = data.Split(';');
        for (int i = 0; i < temp.Length; i++)
        {
            //拆分
            string[] temp_detail = temp[i].Split(',');
            //特服号
            string code = temp_detail[1];
            string mobile = temp_detail[2];//手机号
            // 对接收信息进行url解码
            string content = HttpUtility.UrlDecode(temp_detail[3], Encoding.GetEncoding("gb2312"));//回复的内容需要解码
            string stime = temp_detail[4];//用户回复的时间
            string num = (i + 1).ToString();
            string path = Server.MapPath("data") + "\\data.txt";
            FileInfo f = new FileInfo(path);
            if(!f.Exists)
            {
             FileStream fs=   f.Create();
             fs.Close();
            }
            StreamWriter sw = new StreamWriter(path,true);
            sw.WriteLine("第" + num + "条\r");
            sw.WriteLine("特服号:" + code + "\r");
            sw.WriteLine("手机号:" + mobile + "\r");
            sw.WriteLine("回复内容:" + content + "\r");
            sw.WriteLine("回复时间:" + stime + "\r");
            sw.WriteLine();
            sw.Close();
           
        }
    }
}  


 

四、webservice返回集合对照表:

 

返回值

返回值说明

问题描述

-2 

帐号/密码不正确

1.序列号未注册2.密码加密不正确3.密码已被修改4.序列号已注销

-4

余额不足支持本次发送(或者修改密码长度不正确)

余额不足(或者修改密码长度不在6位到10位之间)

-5

数据格式错误

只能自行调试了。或与技术支持联系

-6

参数有误

看参数传的是否均正常,请调试程序查看各参数

-7

权限受限

该序列号是否已经开通了调用该方法的权限

-8

流量控制错误

-9

扩展码权限错误

该序列号是否已经开通了扩展子号的权限,把ext这个参数置空。

-10

内容长度长

单字节不能超过1000个字符,双字节不能超过500个字符

-11

内部数据库错误

-12

序列号状态错误

序列号是否被禁用

-14

服务器写文件失败

-17

没有权限

如发送彩信仅限于SDK3

-19

禁止同时使用多个接口地址

每个序列号提交只能使用一个接口地址

-20

相同手机号,相同内容重复提交

-22

Ip鉴权失败

提交的IP不是所绑定的IP

-23

缓存无此序列号信息

-601

序列号为空,参数错误

-602

序列号格式错误,参数错误

-603

密码为空,参数错误

-604

手机号码为空,参数错误

-605

内容为空,参数错误

-606

ext长度大于9,参数错误

-607

参数错误 扩展码非数字 

-608

参数错误 定时时间非日期格式

-609

rrid长度大于18,参数错误 

-610

参数错误 rrid非数字

-611

参数错误 内容编码不符合规范

-623

手机个数与内容个数不匹配

-624

扩展个数与手机个数数

-644 

rrid个数与手机个数不一致

注:以上返回值针对个别方法.请具体参看每个用到方法的详细说明。

五、附加说明:

1.接口地址:

常用接口地址:http://sdk.entinfo.cn:8060/webservice.asmx (一般调用)

多线程接口地址:http://sdk.entinfo.cn:8061/webservice.asmx (java、andriod使用)

2.其它说明:

(1)开发使用的帐号必须为SDK开头,如SDK-SSD-010-00001,帐号第一次需要调用Register方法注册一次.仅需注册一次即可,信息必须真实

(2)UnRegister与Register配合使用, 连续使用不得超过10次/天;

(3)群发推荐使用接口方法 mt或者mdSmsSend (仅方法名不同);

3. 郑重声明:

(1)禁止相同的内容多个手机号连续一条一条提交. 否则禁用帐号,由此带来损失由客户自行负责.

(2)请客户提供外网服务器IP以便于绑定IP发送,提高账号的安全性!

(3)在程序里最好有配置文件,程序自动判断当某个接口连接超时提交速度变慢时.程序可以自动切换其它的接口以下是推荐的几个服务器,仅接口地址不同而已.方法全部相同;

地址1:http://sdk.entinfo.cn:8060/webservice.asmx

地址2:http://sdk2.entinfo.cn:8060/webservice.asmx

这些地址都是标准的webservice地址,C#,Java客户可以按照自己熟悉的方式去解析String   

或者

地址1:http://sdk.entinfo.cn:8060/webservice.asmx?wsdl

地址2:http://sdk2.entinfo.cn:8060/webservice.asmx?wsdl

六、示例Demo源代码下载:

  C#短信回复Demo及技术文档  SDK通用版接口文档  所有下载

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值