本文介绍如何使用C# SDK,来完成创建队列、发送消息、接收删除消息和删除队列操作。

步骤一:准备工作

  1. 下载最新版C# SDK,解压后将工程导入到VisualStudio。
  2. 找到工程里四个项目中SDK所在的项目AliyunSDK_MNS,右击项目名,选择重新生成,在bin目录下生成Aliyun.MNS.dll
    说明 其他几个项目里都需要引用这个生成的dll,请配置好其他几个项目的引用。
  3. 在项目AliyunSDK_MNS_Sample里进行配置。
    1. 将项目AliyunSDK_MNS_Sample设置为启动项,并将SyncOperationSample设置为启动对象。
    2. 打开文件SyncOperationSample.cs,在文件的最上方配置AccessKeyID、AccessKeySecret和Endpoint。
      • AccessKeyId、AccessKeySecret
      • Endpoint
        • 访问消息服务MNS的接入地址,请登录MNS控制台,单击右上角获取Endpoint查看。
        • 不同地域的接入地址不同。

步骤二:创建队列

如果之前未创建队列,那么首先需要创建队列。默认创建的队列名称是myqueue,也可以修改代码指定队列名称。

// 1.这里我们指定了Queue的一些属性。对于Queue的属性,请参见Queue。
var createQueueRequest = new CreateQueueRequest
{
    QueueName = _queueName,
    Attributes =
    {
        // VisibilityTimeout是最重要的属性,默认为30秒。
        VisibilityTimeout = 30,
        MaximumMessageSize = 40960,
        MessageRetentionPeriod = 345600,
        // PollingWaitSeconds是非常重要的长轮询超时时间。
        PollingWaitSeconds = 30
    }
};

try
{
    // 2.创建队列。如果不需要特别指定Queue的属性,也可以直接使用client.CreateQueue(_queueName)。
    var queue = client.CreateQueue(createQueueRequest);
    Console.WriteLine("Create queue successfully, queue name: {0}", queue.QueueName);
}
catch (MNSException me)
{
    // 3.如果创建队列出错,可以根据具体的错误Code做处理,也可以分别Catch QueueAlreadyExistException等做单独处理。
    Console.WriteLine("CreateQueue Failed! ErrorCode: " + me.ErrorCode);
}
catch (Exception ex)
{
    Console.WriteLine("Create queue failed, exception info: " + ex.Message);
}           

步骤三:发送消息

创建队列后可以向队列中发送消息。

try
{
    // 1.获取Queue的实例。
    var nativeQueue = client.GetNativeQueue(_queueName);
    // 2.生成SendMessageRequest,可以对Message有一些额外的属性设置。
    var sendMessageRequest = new SendMessageRequest("阿里云<MessageBody>计算");
    // 3.发送消息。也可以直接使用nativeQueue.SendMessage("MessageBody")。
    var sendMessageResponse = nativeQueue.SendMessage(sendMessageRequest);
    Console.WriteLine("Send message succeed“);
}
catch (MNSException me)
{
    // 4.如果创建队列出错,可以根据具体的错误Code做处理,也可以分别Catch QueueNotExistException等做单独处理。
    Console.WriteLine("SendMessage Failed! ErrorCode: " + me.ErrorCode);
}
catch (Exception ex)
{
    Console.WriteLine("Send message failed, exception info: " + ex.Message);
}            

步骤四:接收和删除消息

现在队列里已经有了一条消息,您可以尝试接收消息。

NextVisibleTime是消息服务MNS的消息里一个非常重要的属性。详细说明,请参见QueueMessage

try
{
    // 1.直接调用receiveMessage函数。
    // receiveMessage函数接受waitSeconds参数,无特殊情况建议设置为30。
    // waitSeconds非0表示这次receiveMessage是一次http long polling,如果queue内刚好没有message,那么这次request会在server端等到queue内有消息才返回。最长等待时间为waitSeconds的值,最大为30。
    var receiveMessageResponse = nativeQueue.ReceiveMessage(30);
    // 2.获取ReceiptHandle,这是一个有时效性的Handle,可以用来设置Message的各种属性和删除Message。详情请参见QueueMessage。
    _receiptHandle = message.ReceiptHandle;
}
catch (MNSException me)
{
    // 3.和CreateQueue和SendMessage一样,ReceiveMessage也是有可能出错的,所以这里加上CatchException并做对应的处理。
    Console.WriteLine("ReceiveMessage Failed! ErrorCode: " + me.ErrorCode);
}
catch (Exception ex)
{
    Console.WriteLine("ReceiveMessage failed, exception info: " + ex.Message);
}

// 这里是您自己处理消息的逻辑。Sample里就直接略过这一步了。
// 如果这里发生了程序崩溃或卡住等异常情况,对应的Message会在VisibilityTimeout之后重新可见,从而可以被其他进程处理,避免消息丢失。

// 4.消息处理完成,可以从队列里删除这条消息。
try
{
    // 5.直接调用deleteMessage。
    var deleteMessageResponse = nativeQueue.DeleteMessage(_receiptHandle);
}
catch (MNSException me)
{
    // 6.这里CatchException并做异常处理。
    // 如果是receiptHandle已经过期,那么ErrorCode是MessageNotExist,表示通过这个receiptHandle已经找不到对应的消息。
    // 为了保证receiptHandle不过期,VisibilityTimeout的设置需要保证足够消息处理完成。并且在消息处理过程中,也可以调用changeMessageVisibility这个函数来延长消息的VisibilityTimeout时间。
    Console.WriteLine("DeleteMessage Failed! ErrorCode: " + me.ErrorCode);
}
catch (Exception ex)
{
    Console.WriteLine("Delete message failed, exception info: " + ex.Message);
}            

步骤五:删除队列

删除测试队列。

try 
{
    var deleteQueueResponse = client.DeleteQueue(deleteQueueRequest);
} 
catch (MNSException me)
{
    Console.WriteLine("DeleteQueue Failed! ErrorCode: " + me.ErrorCode);
}
catch (Exception ex)
{
    Console.WriteLine("Delete queue failed, exception info: " + ex.Message);
}