阿里云首页

回执消息-队列模式

本文为您详细介绍隐私号码服务回执消息的队列方式。

简介

当您使用隐私号码服务绑定一组AXB(或者AXN、以下统一以AXB为代表说明)隐私关系后,可以通过使用MNS的Queue模型来接收话单回执消息,话单回执消息时记录了AXB设备证书(ProductKey、DeviceName、DeviceSecret)发生的所有的通话记录行为。

消息的订阅

云通信的所有业务消息都用过MNS消息服务向外发送。用户每订阅一个类别的消息(比如隐私号码话单回执消息(SecretReport)),系统都会为用户分配一个独立的消息队列。用户可以通过阿里云账号拿到一个临时的Token用于获取队列中的消息。用户可以下载Demo,编写简单的消息处理类即可完成消息处理的任务。在页面上订阅消息,订阅完消息后,能拿到消息队列名称(QueueName)。比如:Alicom-Queue-xxxxxx-SecretReport。队列名字每个用户都不同。

消息类型

呼叫发起时话单回执消息SecretStartReport。

出参列表

名称

类型

描述

示例

是否必须

pool_key

String

对应的号池Key。

FC1234567

必须

sub_id

Long

绑定关系ID。

123456

必须

call_id

String

唯一标识一通通话记录的ID。

abcdef1234

必须

phone_no

String

AXB中的A号码。

15000000000

必须

secret_no

String

AXB中的X号码。

1700000000

必须

peer_no

String

AXB中的B号码或者N号码。

1580000000

必须

called_display_no

String

被叫显号。

1580100000

必须

call_type

Interger

呼叫类型。取值:

  • 0:主叫(phone_no打给peer_no)

  • 1:被叫(peer_no打给phone_no)

  • 2:短信发送

  • 3:短信接收

  • 4:呼叫拦截

  • 5:短信收发拦截

0

必须

call_time

String

主叫拨打时间。

"2017-09-01 12:00:00"

必须

out_id

String

外部业务ID。

123456

可选

消息类型

隐私号码目前提供一种消息类型,话单回执消息SecretReport。

参数列表

名称

类型

描述

示例

是否必须

pool_key

String

对应的号池Key。

FC1234567

必须

sub_id

Long

绑定关系ID。

123456

必须

call_id

String

唯一标识一通通话记录的ID。

abcdef1234

必须

phone_no

String

AXB中的A号码。

15000000000

必须

secret_no

String

AXB中的X号码。

1700000000

必须

peer_no

String

AXB中的B号码或者N号码。

1580000000

必须

called_display_no

String

被叫显号。

1580100000

必须

call_type

Interger

呼叫类型。取值:

  • 0:主叫(phone_no打给peer_no)

  • 1:被叫(peer_no打给phone_no)

  • 2:短信发送

  • 3:短信接收

  • 4:呼叫拦截

  • 5:短信收发拦截

0

必须

call_time

String

主叫拨打时间。

"2017-09-01 12:00:00"

必须

start_time

String

被叫接听时间。

"2017-09-01 12:01:00"

必须

ring_time

String

呼叫送被叫端局时,被叫端局响应的时间。

"2017-09-01 12:01:00"

必须

free_ring_time

String

被叫手机真实的振铃时间。free_ring_time>call_out_time代表被叫真实发生了振铃事件,相等代表未振铃。

"2017-09-01 12:01:00"

必须

release_time

String

被叫挂断时间。release_time-start_time代表通话时长。如果结果为0,代表呼叫未接通。

"2017-09-01 12:02:00"

必须

sms_number

Interger

短信长度。

"2017-09-01 12:01:00"

可选

release_dir

Interger

通话释放方向。取值:

  • 0:平台释放

  • 1:主叫挂断

  • 2:被叫挂断

0

必须

out_id

String

外部业务ID。

123456

可选

release_cause

Interger

释放原因

  • 1:未分配的号码

  • 2:无路由到指定的转接网

  • 3:无路由到目的地

  • 4:发送专用信息音

  • 16:正常的呼叫拆线

  • 17:用户忙

  • 18:用户未响应

  • 19:用户未应答

  • 20:用户缺席

  • 21:呼叫拒收

  • 22:号码改变

  • 27:目的地不可达

  • 28:无效的号码格式(地址不全)

  • 29:性能拒绝

  • 31:正常—未指定

  • 34:无电路或通路可用

  • 42:交换设备拥塞

  • 50:所请求的性能未预定

  • 53:CUG中限制去呼叫

  • 55:CUG中限制来呼叫

  • 57:承载能力无权

  • 58:承载能力目前不可用

  • 65:承载能力未实现

  • 69:所请求的性能未实现

  • 87:被叫用户不是CUG的成员

  • 88:不兼容的目的地

  • 90:不存在的CUG

  • 91:无效的转接网选择

  • 95:无效的消息,未指定

  • 97:消息类型不存在或未实现

  • 99:参数不存在或未实现

  • 102:定时器终了时恢复

  • 103:参数不存在或未实现—传递

  • 110:消息带有未被识别的参数—舍弃

  • 111:协议错误,未指定

  • 127:互通,未指定

1

可选

技术对接步骤

  1. 下载消息SDK。

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

    • SDK&DEMOSDK&DEMO下载

  2. 程序样例。

    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.Acs.Dybaseapi.Model.V20170525.QueryTokenForMnsQueueResponse.MessageTokenDTO_;
    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 = "yourAccessId";
            static String accessSecret = "yourAccessSecret";
            static String messageType = "SecretReport";//消息类型目前有4种. 短信回执:SmsReport; 短信上行:SmsUp; 语音回执:VoiceReport; 流量回执:FlowReport;小号话单回执:SecretReport
            static String queueName = "Alicom-Queue-xxxxxxx-SecretReport";// 短信上行的队列名称. 格式是 "前缀(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.MessageTokenDTO_> tokenMap = new Dictionary<string, QueryTokenForMnsQueueResponse.MessageTokenDTO_>();
            Dictionary<string, Queue> queueMap = new Dictionary<string, Queue>();
            public QueryTokenForMnsQueueResponse.MessageTokenDTO_ GetTokenByMessageType(IAcsClient acsClient, String messageType)
            {
                QueryTokenForMnsQueueRequest request = new QueryTokenForMnsQueueRequest();
                request.MessageType = messageType;
                QueryTokenForMnsQueueResponse queryTokenForMnsQueueResponse = acsClient.GetAcsResponse(request);
                QueryTokenForMnsQueueResponse.MessageTokenDTO_ token = queryTokenForMnsQueueResponse.MessageTokenDTO;
                return token;
            }
            /// 处理消息
            public void Handle()
            {
                while (true)
                {
                    try
                    {
                        QueryTokenForMnsQueueResponse.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);
                }
            }
        }
    }
                            
首页 回执消息-队列模式