最大CloudQueueMessage有效负载大小问题

Nec*_*lis 3 c# azure-storage azure-queues

根据MSDN,消息有效载荷可以扩展到8KB(8192字节):

AddMessage方法将消息添加到队列的后面.消息最大可达8 KB.其内容必须采用可以使用UTF-8编码的格式.

但是,当在队列中添加消息时,我收到的消息的例外情况是,有效负载应该小于8192字节,魔术区域似乎大约是6500字节.我发送的数据是纯字符串,其大小是从.Length成员验证的,并且源是从源发送的长度验证的(CRLF分隔符有一个恒定的2字节差异).

所以我的问题是双重的:

1)是否有任何隐藏数据附加到消息有效负载上会导致其大小或导致这种奇怪的行为?(例如限制作为一个整体应用于对象,而不仅仅是它的有效载荷,但即便如此,它如何能够为每条消息占1.5KB?)

2)如何可靠地检查有效载荷是否确实低于8192?

还有一些额外的信息:我正在使用Azure SDK 1.4和VS 2010 Ultimate,运行计算和存储模拟器(我还没有部署这个应用程序)使用SQLExpress(我认为是2008).

还通过代码确认最大大小为8192字节(如果有一些额外的系统强制限制):

Trace.WriteLine("Max Queue Message Size: " + CloudQueueMessage.MaxMessageSize, "CloudQueueMessage");
Run Code Online (Sandbox Code Playgroud)

CloudQueueMessage:最大队列消息大小:8192

use*_*559 9

.NET存储客户端库(Microsoft.WindowsAzure.StorageClient.dll)base-64编码队列消息内容,因此当您使用.NET客户端库时,有效限制为8192*.75 = 6144字节.(那是因为base 64编码增加了1/3的开销.)

(请注意,你不具备立足64编码,这恰好是这个库可以确保队列消息的内容可以安全地嵌入到XML的方式,这是需求上的消息队列服务的地方.)


编辑:这是使用Microsoft.WindowsAzure.StorageClient.Protocol命名空间将原始文本(不是base 64编码)放入队列消息(并随后检索它)的示例代码:

using System;
using System.Net;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
using Microsoft.WindowsAzure.StorageClient.Protocol;

class Program
{
    static void Main(string[] args)
    {
        var q = CloudStorageAccount.Parse("UseDevelopmentStorage=true").CreateCloudQueueClient().GetQueueReference("testqueue");
        q.CreateIfNotExist();

        var req = QueueRequest.PutMessage(new Uri(q.Uri, q.Name + "/messages"), 30, null);
        var body = QueueRequest.GenerateMessageRequestBody("hello world");
        req.ContentLength = body.Length;
        q.ServiceClient.Credentials.SignRequest(req);
        using (var stream = req.GetRequestStream())
        {
            stream.Write(body, 0, body.Length);
            stream.Close();
        }
        req.GetResponse();

        req = QueueRequest.GetMessages(new Uri(q.Uri, q.Name + "/messages"), 30, 32, null);
        q.ServiceClient.Credentials.SignRequest(req);
        using (var response = (HttpWebResponse)req.GetResponse())
        {
            using (var msgResponse = QueueResponse.GetMessages(response))
            {
                foreach (var msg in msgResponse.Messages)
                {
                    Console.WriteLine("MESSAGE: " + msg.Text);
                    q.DeleteMessage(msg.Id, msg.PopReceipt);
                }
            }
        }

        q.Delete();
    }
}
Run Code Online (Sandbox Code Playgroud)