[英]Azure Service Bus Queue - QueueClient.Receive() returning null BrokeredMessage when messages are in the queue
I have messages in an Azure Service Bus Queue that I can't receive. 我在Azure服务总线队列中收到无法接收的消息。 And I'm not getting any indicator as to what the problem is. 而且我没有任何有关问题所在的指标。 I think it has something to do with message size. 我认为这与邮件大小有关。 You can see from the code below that I'm using OpenFileDialog. 您可以从下面的代码中看到我正在使用OpenFileDialog。 I'm selecting jpeg images and they are getting sent to the queue. 我正在选择jpeg图像,它们正被发送到队列中。 Now, when I send small images less than about 50KB, they are getting displayed fine by the receiving process, but larger ones over 100KB are just staying in the queue. 现在,当我发送小于50KB的小图像时,在接收过程中它们可以很好地显示,但是大于100KB的大图像则只留在队列中。 MSDN says that message size limit is 256KB so I'm not sure what is going on here. MSDN说消息大小限制为256KB,所以我不确定这里发生了什么。
I have two classes. 我有两节课。 One is SendToQueue and the other is RecvFromQueue. 一个是SendToQueue,另一个是RecvFromQueue。 Here is the code. 这是代码。
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();
}
}
}
}
}
Message size limit is 256 KB but this includes both the headers and the body, where the maximum header size is 64 KB . 邮件大小限制为256 KB,但这包括标头和正文,最大标头大小为64 KB 。 In your case header is not an issue (less than 1 KB) 在您的情况下,标题不是问题(小于1 KB)
I run your example with few minor changes: 我运行您的示例时,做了一些小的更改:
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();
And I was able to successfully send and receive message with this 254 KB image 而且我能够使用此254 KB图像成功发送和接收消息
If your message would be too large you would get MessageSizeExceededException when you call client.Send(msg);
如果您的消息太大,则在调用client.Send(msg);
时会收到MessageSizeExceededException client.Send(msg);
You can run this test on your queue to see if you can receive all messages, it passes for me. 您可以在队列上运行此测试,以查看是否可以接收所有消息,它对我来说是合格的。
[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();
}
}
I stumbled upon this question helping a co-worker. 我偶然发现了这个问题,为同事提供了帮助。 (I promise it was another dev!) (我保证这是另一个开发者!)
We ran into this issue while he was running code that checked the queue.MessageCount (setting it to a variable of name myQMessageCount ) and the code had "while (myQMessageCount > 0)" and he was resetting the queuecount after every msg.Complete (inside the same while loop) 当他运行检查队列的代码时,我们遇到了这个问题。MessageCount(将其设置为名为myQMessageCount的变量),并且代码具有“ while(myQMessageCount> 0)”,并且他在每个msg.Complete(在相同的while循环内)
Turns out .MessageCount is a "sum" of all messages in the queue, including Active (the ones you should be able to read) and dead letters and others. 原来,.MessageCount是队列中所有消息的“总和”,包括活动(您应该能够阅读的消息),不活动的字母和其他消息。
So (1), the fix was for him to change his code to check the ActiveMessageCount, not the .MessageCount 因此(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;
and (2), after we discussed it, it probably isn't wise to keep checking the ActiveMessageCount, and just let a returned null BrokeredMessage be the check that there are no more messages in the queue. (2),在我们讨论之后,继续检查ActiveMessageCount是不明智的,只让返回的null BrokeredMessage作为检查队列中是否没有消息的检查。
Anyway. 无论如何。 I am posting this answer here for future readers who might get stuck on some custom read-queue code they are writing. 我将这个答案发布在这里,供将来的读者使用,他们可能会陷入他们正在编写的一些自定义阅读队列代码中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.