Как удалить сообщение DeadLetter в разделе служебной шины Azure
Я пишу кусок кода, который позволит нам:
- Просмотр списка всех недоставленных сообщений, которые существуют в разделе служебной шины Azure (Peek)
- Исправить и отправить их обратно в тему
- Удалите их из очереди недоставленных писем после повторной отправки.
У меня нет проблем с первыми 2 пунктами; используя режим получения Peek, я могу показать список сообщений, и мы можем редактировать и отправлять без проблем.
Проблема возникает, когда я хочу удалить сообщение из очереди недоставленных сообщений.
Как мы можем сделать это на уровне сообщения? Мы можем захотеть удалить только 2 из сообщений, находящихся в очереди недоставленных сообщений, и оставить остальные для последующего просмотра. Звонит .Complete()
удалить сообщение в очереди недоставленных писем, как в основной подписке?
Для справки; вот наш код для получения SubscriptionClient
для очереди мертвых писем:
private SubscriptionClient GetOrCreateSubscriptionClient(string connectionString)
{
if (!NamespaceManager.TopicExists(_topicName))
{
NamespaceManager.CreateTopic(new TopicDescription(_topicName)
{
MaxSizeInMegabytes = 5120,
DefaultMessageTimeToLive = TimeSpan.FromSeconds(DEFAULT_LOCK_DURATION_IN_SECONDS)
});
}
if (!NamespaceManager.SubscriptionExists(_topicName, _subscriptionName))
{
NamespaceManager.CreateSubscription(_topicName, _subscriptionName);
}
var deadLetterPath = SubscriptionClient.FormatDeadLetterPath(_topicName, _subscriptionName);
var client = SubscriptionClient.CreateFromConnectionString(
connectionString, deadLetterPath, _subscriptionName, ReceiveMode.PeekLock);
return client;
}
3 ответа
Да, выполнение вызова со ссылкой на сообщение с посредником, полученное из очереди недоставленных сообщений, приведет к удалению его из очереди недоставленных сообщений.
Вот как вы можете получить список всех сообщений в очереди недоставленных сообщений:
public async Task<IEnumerable<BrokeredMessage>> GetDeadLetterMessagesAsync(string connectionString,
string queueName)
{
var queue = QueueClient.CreateFromConnectionString(connectionString, QueueClient.FormatDeadLetterPath(queueName));
var messageList = new List<BrokeredMessage>();
BrokeredMessage message;
do
{
message = await queue.PeekAsync();
if (message != null)
{
messageList.Add(message);
}
} while (message != null);
return messageList;
}
Используя SequenceNumber, вы можете затем удалить конкретное сообщение:
public async Task DeleteDeadLetterMessageAsync(string connectionString, string queueName, long sequenceNumber)
{
var deadLetterQueue = QueueClient.CreateFromConnectionString(connectionString, QueueClient.FormatDeadLetterPath(queueName));
var msg = await deadLetterQueue.PeekAsync(sequenceNumber);
if (msg.SequenceNumber == sequenceNumber)
{
msg = await deadLetterQueue.ReceiveAsync();
await msg.CompleteAsync();
}
}
Обратите внимание, что Peek может вернуть другое сообщение, если нет сообщения с указанным SequenceNumber. Поэтому вам нужно проверить SequenceNumber, чтобы вы не удалили неправильное сообщение.
Обновлен код для удаления сообщения из очереди недоставленных сообщений с использованием нового
ServiceBusClient
из
azure.messaging.servicebus
:
public async Task DeleteDeadLetterMessageAsync(string connectionString, string queueName, long sequenceNumber)
{
var serviceBusClient = new ServiceBusClient(connectionString);
var receiverOptions = new ServiceBusReceiverOptions { SubQueue = SubQueue.DeadLetter };
var receiver = serviceBusClient.CreateReceiver(queueName, receiverOptions);
var msg = await receiver.PeekMessageAsync(sequenceNumber);
if (msg.SequenceNumber == sequenceNumber)
{
msg = await receiver.ReceiveMessageAsync();
await receiver.CompleteMessageAsync(msg);
}
}