2014-11-14 131 views
0

我在Azure服务总线队列中收到我无法接收的邮件。我没有得到任何问题的指标。我认为这与邮件大小有关。你可以从下面的代码中看到我正在使用OpenFileDialog。我正在选择jpeg图像,并将它们发送到队列中。现在,当我发送小于约50KB的小图片时,它们在接收过程中显示得很好,但超过100KB的较大图片只停留在队列中。 MSDN表示邮件大小限制为256KB,因此我不确定这里发生了什么。Azure服务总线队列 - QueueClient.Receive()当邮件在队列中时返回null BrokeredMessage

我有两个类。一个是SendToQueue,另一个是RecvFromQueue。这是代码。

using System; 
using System.IO; 
using System.Windows.Forms; 
using Microsoft.ServiceBus; 
using Microsoft.ServiceBus.Messaging; 
using Microsoft.WindowsAzure; 

namespace ServiceBusQueueApp 
{ 
    public class SendToQueue 
    { 
     private const string c_testqueue = "TestQueue"; 

     [STAThreadAttribute] 
     static void Main(string[] args) 
     { 
      // Configure Queue Settings 
      QueueDescription qd = new QueueDescription(c_testqueue) 
      { 
       MaxSizeInMegabytes = 5120, 
       DefaultMessageTimeToLive = new TimeSpan(1, 1, 0) 
      }; 

      // Create a new Queue with custom settings 
      string connectionString = 
       CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString"); 

      var namespaceManager = 
       NamespaceManager.CreateFromConnectionString(connectionString); 

      if (!namespaceManager.QueueExists(c_testqueue)) 
      { 
       namespaceManager.CreateQueue(qd); 
      } 

      namespaceManager.DeleteQueue(qd.Path); 
      namespaceManager.CreateQueue(qd); 

      QueueClient client = QueueClient.CreateFromConnectionString(connectionString, c_testqueue); 

      double maxSize = Math.Pow(2, 18); 

      OpenFileDialog openFile = new OpenFileDialog(); 
      while (true) 
      { 
       if (openFile.ShowDialog() == DialogResult.Cancel) 
       { 
        break; 
       } 

       var messageBodyStream = new FileStream(openFile.FileName, System.IO.FileMode.Open, FileAccess.Read, FileShare.ReadWrite); 

       if (messageBodyStream.Length > maxSize) 
       { 
        MessageBox.Show("File is larger than 256KB."); 
        continue; 
       } 
       BrokeredMessage msg = 
        new BrokeredMessage(messageBodyStream); 
       msg.Properties["MyProperty"] = "Test Value"; 


       try 
       { 
        //send msg to the queue 
        client.Send(msg); 
       } 
       catch (Exception exception) 
       { 
        MessageBox.Show(exception.Message); 
        throw; 
       } 
      } 

     } 
    } 
} 


using System; 
using System.Diagnostics; 
using System.IO; 
using System.Threading; 
using System.Windows.Forms; 
using Microsoft.ServiceBus; 
using Microsoft.ServiceBus.Messaging; 
using Microsoft.WindowsAzure; 

namespace ServiceBusQueueApp 
{ 
    class RecvFromQueue 
    { 

     private const string c_testqueue = "TestQueue"; 

     static void Main(string[] args) 
     { 
      // Create a new Queue with custom settings 
      string connectionString = 
       CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString"); 

      var namespaceManager = 
       NamespaceManager.CreateFromConnectionString(connectionString); 

      if (!namespaceManager.QueueExists(c_testqueue)) 
      { 
       MessageBox.Show("Queue does not exist."); 
       throw new Exception("Queue does not exist."); 
      } 

      QueueClient client = QueueClient.CreateFromConnectionString(connectionString, c_testqueue); 

      while (true) 
      { 
       BrokeredMessage message = client.Receive(); 

       if (message == null) 
       { 
        continue; 
       } 
       try 
       { 
        Stream fstream = message.GetBody<Stream>(); 
        byte[] buffer = new byte[fstream.Length]; 
        fstream.Read(buffer, 0, (int)fstream.Length); 
        File.WriteAllBytes(@"C:\users\roberthar\pictures\testpic.png", buffer); 
        fstream.Close(); 

        Process paint = new Process(); 
        paint.StartInfo.FileName = @"C:\Windows\System32\mspaint.exe"; 
        paint.StartInfo.Arguments = @"C:\users\roberthar\pictures\testpic.png"; 
        paint.Start(); 

        Thread.Sleep(3000); 

        paint.Close(); 

        // Remove message from queue 
        message.Complete(); 
       } 
       catch (Exception exception) 
       { 
        // Indicate a problem, unlock message in queue 
        message.Abandon(); 
       } 
      } 
     } 
    } 
} 
+0

对不起,我意识到这是很晚,但我会建议你在接收代码中添加某种日志记录。此代码捕获任何异常(与队列相关或与文件相关),然后放弃该消息而不记录。除非记录异常详细信息,否则不会看到实际的错误(因此可以修复它)。 – Joon 2017-04-04 16:09:44

回答

1

消息大小限制为256 KB但这既包括标头和主体,其中最大报头大小是64 KB。在你的情况报头是不是一个问题(小于1 KB)

我有一些小的变化运行例如:

  string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, 
       string.Format("testpic_{0}_{1}_{2}.png", now.Hour, now.Minute, now.Second)); 
      File.WriteAllBytes(filePath, buffer); 
      fstream.Close(); 

      Process paint = new Process(); 
      paint.StartInfo.FileName = @"C:\Windows\System32\mspaint.exe"; 
      paint.StartInfo.Arguments = filePath; 
      paint.Start(); 

,我能够与this 254 KB image

成功地发送和接收消息如果你的信息会太大,你会得到MessageSizeExceededException当你调用client.Send(msg);

您可以在队列中运行这个测试,看看你能收到的所有消息,它传递给我。

[Fact] 
    public void MaxMessageSize() 
    { 
     var sender = CreateClient(); 
     var reciver = CreateClient(); 
     for (int i = 1; i < 255; i++) 
     { 
      var size = i*1024; 
      var buffer = new byte[size]; 
      random.NextBytes(buffer); 
      BrokeredMessage msg = 
       new BrokeredMessage(buffer); 
      msg.Properties["size"] = size; 
      sender.Send(msg); 
      var message = reciver.Receive(); 
      Assert.NotNull(message); 
      Assert.Equal(message.Properties["size"], size); 
      var bufferReceived = message.GetBody<byte[]>(); 
      Assert.Equal(buffer, bufferReceived); 
      message.Complete(); 
     } 
    } 

完全gist here

+0

使用您提供的要点(通过从控制台应用程序运行简单重构)我无法接收邮件大小超过64kb的邮件。当消息大于256kb时,它只发送失败 – BFreeman 2015-03-09 20:40:06

0

我偶然发现了这个问题,帮助同事。 (我承诺这是另一个开发!)

当他运行检查队列的代码时,我们遇到了这个问题.MessageCount(将其设置为名称为myQMessageCount的变量)并且代码具有“while(myQMessageCount> 0) “并且他在每个msg.Complete(在相同的while循环内)后重置队列计数

结果.MessageCount是队列中所有消息的”总和“,包括Active(应该能够读取的那些消息)和死信等。

所以(1),该修补程序是为他修改代码来检查ActiveMessageCount,而不是.MessageCount

   Microsoft.ServiceBus.Messaging.QueueDescription qd = myMicrosoftdotServiceBusdotNamespaceManager.GetQueue(qName); 
       string deadLetterQueueName = QueueClient.FormatDeadLetterPath(qd.Path); 
       int activeMessageCount = qd.MessageCountDetails.ActiveMessageCount; 
       int deadLetterMessageCount = qd.MessageCountDetails.DeadLetterMessageCount; 
       int scheduledMessageCount = qd.MessageCountDetails.ScheduledMessageCount; 
       int transferDeadLetterMessageCount = qd.MessageCountDetails.TransferDeadLetterMessageCount; 
       int transferMessageCount = qd.MessageCountDetails.TransferMessageCount; 

和(2),我们讨论后,它可能不是明智的继续检查ActiveMessageCount,并让返回的空BrokeredMessage成为检查队列中没有更多消息的检查。

无论如何。我将这个答案发布给未来的读者,他们可能会遇到他们正在编写的一些自定义读取队列代码。