本文为您介绍.NET调用短信消息API的操作流程。
简介
当您使用短信的API接口发送短信后,可以通过使用MNS的Queue模型来接收短信的回执消息,假如服务出现异常情况时(如网络问题),导致消息回执未成功获取,还可以通过短信发送记录查询API接口进行一定的补偿(目前支持30天内发送记录的查询,可查询一天的发送数据)。
注意 使用短信服务新版SDK调用API接口,请查看新版SDK参考和API参考。
消息的订阅
- 云通信的所有业务消息都通过MNS消息服务向外发送。用户每订阅一个类别的消息(比如上行短信消息SmsUp),系统都会为用户分配一个独立的消息队列。
- 用户可以通过阿里云账号拿到一个临时的token用于获取队列中的消息。用户可以下载demo,编写简单的消息处理类即可完成消息处理的任务。
- 在页面上订阅消息,订阅完消息后,能拿到消息队列名称(queueName)。比如:Alicom-Queue-xxxxxx-SmsReport 。队列名字每个用户都不同。
路径:短信产品进入控制台→应用开发→接口调用→云通信消息接收→短信状态报告接收→向右滑动 (MNS消息队列消费模式。接收消息队列信息,请下载消息服务SDK进行程序编写,详见API文档)位置如下图所有示;点击进入控制台。
消息类型
短信提供2种消息类型SmsReport(短信回执报告消息)和 SmsUp(上行短信消息)。
- 通过订阅SmsReport短信状态报告,可以获知每条短信的发送情况,了解短信是否达到终端用户的状态与相关信息。
- 通过订阅SmsUp上行短信消息,可以获知终端用户回复短信的内容。
短信回执消息SmsReport消息体格式
名称 | 类型 | 描述 | 示例 |
---|---|---|---|
phone_number | String | 短信接收号码。 | 13000000000 |
success | Boolean | 发送是否成功。 | true |
biz_id | String | 发送回执ID。 | 1234^345 |
out_id | String | 调用发送短信接口时传的outId。 | 123456 |
send_time | String | 转发给运营商的时间。 | 2017-06-01 10:00:00 |
report_time | String | 收到运营商回执的时间。 | 2017-06-01 10:00:05 |
err_code | String | 错误码。 | UNKNOW |
err_msg | String | 错误信息。 | 未知异常 |
sms_size | String | 140字节算一条短信,短信长度超过140字节时会拆分成多条短信发送。 | 1,2,3 |
上行短信消息SmsUp
名称 | 类型 | 描述 | 示例 |
---|---|---|---|
phone_number | String | 短信接收号码。 | 13000000000 |
content | String | 短信内容。 | true |
sign_name | String | 短信签名。 | 【阿里云】 |
send_time | String | 时间。 | 2017-06-01 10:00:00 |
dest_code | String | 扩展码。 | 123456 |
sequence_id | Double | 消息序列ID。 | 123456 |
技术对接步骤
下载消息SDK
下载对应短信的消息DEMO工程,工程所需要的所有依赖包都放在DEMO工程的lib目录下,将对应的包引入到您的工程当中既可按照DEMO样例编写接收消息的程序。
SDK&DEMO【下载地址】
编写样例程序
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Aliyun.Acs.Core;
using Aliyun.Acs.Core.Exceptions;
using Aliyun.Acs.Core.Profile;
using Aliyun.Acs.Dybaseapi.Model.V20170525;
using Aliyun.MNS;
using Aliyun.MNS.Model;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication7
{
class Program
{
private static int maxThread = 2;
static String accessId = ""; //你的accessKeyId,参考本文档步骤2
static String accessSecret = "";//你的accessKeySecret,参考本文档步骤2
static String messageType = "SmsReport";//消息类型目前有4种. 短信回执:SmsReport; 短信上行:SmsUp; 语音回执:VoiceReport; 流量回执:FlowReport;
static String queueName = "Alicom-Queue-17888888794453-SmsReport";// 短信上行的队列名称. 格式是 "前缀(Alicom-Queue-)+阿里云uid+消息类型"
static String domainForPop = "dybaseapi.aliyuncs.com";
static String regionIdForPop = "cn-hangzhou";//(请勿修改)
static String productName = "Dybaseapi";
static IAcsClient acsClient = null;
public static IAcsClient InitAcsClient(String regionIdForPop, String accessId, String accessSecret, String productName, String domainForPop)
{
IClientProfile profile = DefaultProfile.GetProfile(regionIdForPop, accessId, accessSecret);
DefaultProfile.AddEndpoint(regionIdForPop, regionIdForPop, productName, domainForPop);
IAcsClient acsClient = new DefaultAcsClient(profile);
return acsClient;
}
// 初始化环境
private static void InitData()
{
acsClient = InitAcsClient(regionIdForPop, accessId, accessSecret, productName, domainForPop);
}
static void Main(string[] args)
{
InitData();
for (int i = 0; i < maxThread; i++)
{
TestTask testTask = new TestTask("PullMessageTask-thread-" + i, messageType, queueName, acsClient);
Thread t = new Thread(new ThreadStart(testTask.Handle));
//启动线程
t.Start();
}
Console.ReadKey();
}
}
class TestTask
{
private object o = new object();
private int sleepTime = 50;
public String name { get; private set; }
public String messageType { get; private set; }
public String queueName { get; private set; }
public int TaskID { get; private set; }
public IAcsClient acsClient { get; private set; }
public TestTask(String name, String messageType, String queueName, IAcsClient acsClient)
{
this.name = name;
this.messageType = messageType;
this.queueName = queueName;
this.acsClient = acsClient;
}
long bufferTime = 60 * 2;//过期时间小于2分钟则重新获取,防止服务器时间误差
String mnsAccountEndpoint = "https://1943695596114318.mns.cn-hangzhou.aliyuncs.com/";//阿里通信消息的endpoint,固定
Dictionary<string, QueryTokenForMnsQueueResponse.QueryTokenForMnsQueue_MessageTokenDTO> tokenMap = new Dictionary<string, QueryTokenForMnsQueueResponse.QueryTokenForMnsQueue_MessageTokenDTO>();
Dictionary<string, Queue> queueMap = new Dictionary<string, Queue>();
public QueryTokenForMnsQueueResponse.QueryTokenForMnsQueue_MessageTokenDTO GetTokenByMessageType(IAcsClient acsClient, String messageType)
{
QueryTokenForMnsQueueRequest request = new QueryTokenForMnsQueueRequest();
request.MessageType = messageType;
QueryTokenForMnsQueueResponse queryTokenForMnsQueueResponse = acsClient.GetAcsResponse(request);
QueryTokenForMnsQueueResponse.QueryTokenForMnsQueue_MessageTokenDTO = queryTokenForMnsQueueResponse.MessageTokenDTO;
return token;
}
/// 处理消息
public void Handle()
{
while (true)
{
try
{
QueryTokenForMnsQueueResponse.QueryTokenForMnsQueue_MessageTokenDTO token = null;
Queue queue = null;
lock (o)
{
if (tokenMap.ContainsKey(messageType))
{
token = tokenMap[messageType];
}
if (queueMap.ContainsKey(queueName))
{
queue = queueMap[queueName];
}
TimeSpan ts = new TimeSpan(0);
if (token != null)
{
DateTime b = Convert.ToDateTime(token.ExpireTime);
DateTime c = Convert.ToDateTime(DateTime.Now);
ts = b - c;
}
if (token == null || ts.TotalSeconds < bufferTime || queue == null)
{
token = GetTokenByMessageType(acsClient, messageType);
IMNS client = new Aliyun.MNS.MNSClient(token.AccessKeyId, token.AccessKeySecret, mnsAccountEndpoint, token.SecurityToken);
queue = client.GetNativeQueue(queueName);
if (tokenMap.ContainsKey(messageType))
{
tokenMap.Remove(messageType);
}
if (queueMap.ContainsKey(queueName))
{
queueMap.Remove(queueName);
}
tokenMap.Add(messageType, token);
queueMap.Add(queueName, queue);
}
}
BatchReceiveMessageResponse batchReceiveMessageResponse = queue.BatchReceiveMessage(16);
List<Message> messages = batchReceiveMessageResponse.Messages;
for (int i = 0; i <= messages.Count - 1; i++)
{
try
{
byte[] outputb = Convert.FromBase64String(messages[i].Body);
string orgStr = Encoding.UTF8.GetString(outputb);
System.Console.WriteLine(orgStr);
//TODO 具体消费逻辑,待客户自己实现.
//消费成功的前提下删除消息
queue.DeleteMessage(messages[i].ReceiptHandle);
}
catch (Exception e)
{
System.Console.WriteLine("Hello World!", e);
}
}
}
catch (Exception e)
{
System.Console.WriteLine("Handle exception", e);
}
Thread.Sleep(sleepTime);
}
}
}
}
在文档使用中是否遇到以下问题
更多建议
匿名提交