全部产品
弹性计算 会员服务 网络 安全 移动云 数加·大数据分析及展现 数加·大数据应用 管理与监控 云通信 阿里云办公 培训与认证 智能硬件
存储与CDN 数据库 域名与网站(万网) 应用服务 数加·人工智能 数加·大数据基础服务 互联网中间件 视频服务 开发者工具 解决方案 物联网 更多
短信服务

短信消息API---.NET

更新时间:2018-02-12 11:46:52

简介

当您使用短信的API接口发送短信后,可以通过使用MNS的Queue模型来接收短信的回执消息,假如服务出现异常情况时(如网络问题),导致消息回执未成功获取,还可以通过短信发送记录查询API接口进行一定的补偿(目前支持30天内发送记录的查询,可查询一天的发送数据)。

消息的订阅

  • 云通信的所有业务消息都用过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 时间 20150101120000
dest_code String 扩展码 123456
sequence_id Double 消息序列ID 123456

技术对接步骤

下载消息SDK

下载对应语音的消息DEMO工程,工程所需要的所有依赖包都放在DEMO工程的lib目录下,将对应的包引入到您的工程当中既可按照DEMO样例编写接收消息的程序。

SDK&DEMO【下载地址】

编写样例程序

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Aliyun.Acs.Core;
  6. using Aliyun.Acs.Core.Exceptions;
  7. using Aliyun.Acs.Core.Profile;
  8. using Aliyun.Acs.Dybaseapi.Model.V20170525;
  9. using Aliyun.MNS;
  10. using Aliyun.MNS.Model;
  11. using System.Threading;
  12. using System.Threading.Tasks;
  13. namespace ConsoleApplication7
  14. {
  15. class Program
  16. {
  17. private static int maxThread = 2;
  18. static String accessId = ""; //你的accessKeyId,参考本文档步骤2
  19. static String accessSecret = "";//你的accessKeySecret,参考本文档步骤2
  20. static String messageType = "SmsReport";//消息类型目前有4种. 短信回执:SmsReport; 短信上行:SmsUp; 语音回执:VoiceReport; 流量回执:FlowReport;
  21. static String queueName = "Alicom-Queue-17888888794453-SmsReport";// 短信上行的队列名称. 格式是 "前缀(Alicom-Queue-)+阿里云uid+消息类型"
  22. static String domainForPop = "dybaseapi.aliyuncs.com";
  23. static String regionIdForPop = "cn-hangzhou";//(请勿修改)
  24. static String productName = "Dybaseapi";
  25. static IAcsClient acsClient = null;
  26. public static IAcsClient InitAcsClient(String regionIdForPop, String accessId, String accessSecret, String productName, String domainForPop)
  27. {
  28. IClientProfile profile = DefaultProfile.GetProfile(regionIdForPop, accessId, accessSecret);
  29. DefaultProfile.AddEndpoint(regionIdForPop, regionIdForPop, productName, domainForPop);
  30. IAcsClient acsClient = new DefaultAcsClient(profile);
  31. return acsClient;
  32. }
  33. // 初始化环境
  34. private static void InitData()
  35. {
  36. acsClient = InitAcsClient(regionIdForPop, accessId, accessSecret, productName, domainForPop);
  37. }
  38. static void Main(string[] args)
  39. {
  40. InitData();
  41. for (int i = 0; i < maxThread; i++)
  42. {
  43. TestTask testTask = new TestTask("PullMessageTask-thread-" + i, messageType, queueName, acsClient);
  44. Thread t = new Thread(new ThreadStart(testTask.Handle));
  45. //启动线程
  46. t.Start();
  47. }
  48. Console.ReadKey();
  49. }
  50. }
  51. class TestTask
  52. {
  53. private object o = new object();
  54. private int sleepTime = 50;
  55. public String name { get; private set; }
  56. public String messageType { get; private set; }
  57. public String queueName { get; private set; }
  58. public int TaskID { get; private set; }
  59. public IAcsClient acsClient { get; private set; }
  60. public TestTask(String name, String messageType, String queueName, IAcsClient acsClient)
  61. {
  62. this.name = name;
  63. this.messageType = messageType;
  64. this.queueName = queueName;
  65. this.acsClient = acsClient;
  66. }
  67. long bufferTime = 60 * 2;//过期时间小于2分钟则重新获取,防止服务器时间误差
  68. String mnsAccountEndpoint = "https://1943695596114318.mns.cn-hangzhou.aliyuncs.com/";//阿里通信消息的endpoint,固定
  69. Dictionary<string, QueryTokenForMnsQueueResponse.QueryTokenForMnsQueue_MessageTokenDTO> tokenMap = new Dictionary<string, QueryTokenForMnsQueueResponse.QueryTokenForMnsQueue_MessageTokenDTO>();
  70. Dictionary<string, Queue> queueMap = new Dictionary<string, Queue>();
  71. public QueryTokenForMnsQueueResponse.QueryTokenForMnsQueue_MessageTokenDTO GetTokenByMessageType(IAcsClient acsClient, String messageType)
  72. {
  73. QueryTokenForMnsQueueRequest request = new QueryTokenForMnsQueueRequest();
  74. request.MessageType = messageType;
  75. QueryTokenForMnsQueueResponse queryTokenForMnsQueueResponse = acsClient.GetAcsResponse(request);
  76. QueryTokenForMnsQueueResponse.QueryTokenForMnsQueue_MessageTokenDTO = queryTokenForMnsQueueResponse.MessageTokenDTO;
  77. return token;
  78. }
  79. /// 处理消息
  80. public void Handle()
  81. {
  82. while (true)
  83. {
  84. try
  85. {
  86. QueryTokenForMnsQueueResponse.QueryTokenForMnsQueue_MessageTokenDTO token = null;
  87. Queue queue = null;
  88. lock (o)
  89. {
  90. if (tokenMap.ContainsKey(messageType))
  91. {
  92. token = tokenMap[messageType];
  93. }
  94. if (queueMap.ContainsKey(queueName))
  95. {
  96. queue = queueMap[queueName];
  97. }
  98. TimeSpan ts = new TimeSpan(0);
  99. if (token != null)
  100. {
  101. DateTime b = Convert.ToDateTime(token.ExpireTime);
  102. DateTime c = Convert.ToDateTime(DateTime.Now);
  103. ts = b - c;
  104. }
  105. if (token == null || ts.TotalSeconds < bufferTime || queue == null)
  106. {
  107. token = GetTokenByMessageType(acsClient, messageType);
  108. IMNS client = new Aliyun.MNS.MNSClient(token.AccessKeyId, token.AccessKeySecret, mnsAccountEndpoint, token.SecurityToken);
  109. queue = client.GetNativeQueue(queueName);
  110. if (tokenMap.ContainsKey(messageType))
  111. {
  112. tokenMap.Remove(messageType);
  113. }
  114. if (queueMap.ContainsKey(queueName))
  115. {
  116. queueMap.Remove(queueName);
  117. }
  118. tokenMap.Add(messageType, token);
  119. queueMap.Add(queueName, queue);
  120. }
  121. }
  122. BatchReceiveMessageResponse batchReceiveMessageResponse = queue.BatchReceiveMessage(16);
  123. List<Message> messages = batchReceiveMessageResponse.Messages;
  124. for (int i = 0; i <= messages.Count - 1; i++)
  125. {
  126. try
  127. {
  128. byte[] outputb = Convert.FromBase64String(messages[i].Body);
  129. string orgStr = Encoding.UTF8.GetString(outputb);
  130. System.Console.WriteLine(orgStr);
  131. //TODO 具体消费逻辑,待客户自己实现.
  132. //消费成功的前提下删除消息
  133. queue.DeleteMessage(messages[i].ReceiptHandle);
  134. }
  135. catch (Exception e)
  136. {
  137. System.Console.WriteLine("Hello World!", e);
  138. }
  139. }
  140. }
  141. catch (Exception e)
  142. {
  143. System.Console.WriteLine("Handle exception", e);
  144. }
  145. Thread.Sleep(sleepTime);
  146. }
  147. }
  148. }
  149. }
本文导读目录