2014-11-14 1 views
0

수신 할 수없는 Azure 서비스 대기열에 메시지가 있습니다. 그리고 나는 문제가 무엇인지에 관해 어떤 지표도 얻지 못하고있다. 메시지 크기와 관련이 있다고 생각합니다. 아래 코드에서 OpenFileDialog를 사용하고있는 것을 볼 수 있습니다. jpeg 이미지를 선택 중이며 대기열로 전송됩니다. 이제 약 50KB 미만의 작은 이미지를 보내면 수신 프로세스에 의해 잘 표시되지만 100KB를 넘는 이미지는 대기열에 머물러 있습니다. MSDN에서는 메시지 크기 제한이 256KB이므로 여기에서 무슨 일이 일어나고 있는지 잘 모르겠습니다.메시지가 대기열에있을 때 Azure 서비스 버스 대기열 - QueueClient.Receive()가 null을 반환합니다.

두 클래스가 있습니다. 하나는 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

답변

1

메시지 크기 제한은 2백56킬로바이트하지만 이것은 헤더와 헤더 최대 크기 64킬로바이트 인 체 모두를 포함한다. 귀하의 경우에는 헤더 (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

0

나는 동료를 돕는이 질문에 비틀 거렸다.

queue.MessageCount (name myQMessageCount 변수로 설정)를 검사하는 코드를 실행하는 동안이 문제가 발생하여 코드에 "while (myQMessageCount> 0) "그리고 그는 msg.Complete (모든 while 루프 내에서) 이후에 대기열을 재설정했습니다.

.MessageCount는 대기열에있는 모든 메시지의"합계 "로 읽을 수 있어야합니다) 및 죽은 편지 및 기타.

그래서 (1), 수정은 우리가 그것을 논의 후

   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 아닌 .MessageCount을 확인하기 위해 자신의 코드를 변경 그를 위해이었다 ActiveMessageCount를 계속 확인하고 반환 된 null BrokeredMessage가 대기열에 더 이상 메시지가 없다는 검사가되도록합니다.

어쨌든. 내가 쓰고있는 커스텀 read-queue 코드에 붙어있는 미래의 독자들을 위해이 대답을 게시하고있다.

관련 문제