当我使用以下内容时:
var deadLetterPath = SubscriptionClient.FormatDeadLetterPath(topicPath,subName);
var client = SubscriptionClient.CreateFromConnectionString(connectionString, deadLetterPath, subName);
我收到了InvalidOperationException
无法在子队列上直接创建客户端。在上创建一个客户端 主队列并使用它来创建适当的接收器 子队列
azure文档的某些部分说使用SubscriptionClient.CreateReceiver来访问子队列,但该方法不存在。
答案 0 :(得分:19)
这种方法对你有用吗?
MessagingFactory factory = MessagingFactory.CreateFromConnectionString(cnxString);
var deadLetterPath = SubscriptionClient.FormatDeadLetterPath(topicPath,subName);
var dlqReceiver = factory.CreateMessageReceiver(deadLetterPath, ReceiveMode.ReceiveAndDelete);
我没有在这里测试(在会议中),但试一试
欢呼声
答案 1 :(得分:13)
使用Azure Service Bus对死信队列进行常规命名:
因此,您可以像访问队列一样访问死信队列。
从@SamVanhoutte回答,您可以看到ServiceBus框架提供了格式化死信队列名称的方法:
对于服务总线队列:QueueClient.FormatDeadLetterPath(queuePath)
对于服务总线订阅:SubscriptionClient.FormatDeadLetterPath(topicPath, subscriptionName)
我编写了两个小方法来为队列和订阅创建一个消息接收器,您可以在其中设置是否需要交易信件队列:
/// <summary>
/// Create a new <see cref="MessageReceiver"/> object using the specified Service Bus Queue path.
/// </summary>
/// <param name="connectionString">The connection string to access the desired service namespace.</param>
/// <param name="queuePath">The Service Bus Queue path.</param>
/// <param name="isDeadLetter">True if the desired path is the deadletter queue.</param>
public static MessageReceiver CreateMessageReceiver(string connectionString, string queuePath,
bool isDeadLetter = false)
{
return MessagingFactory.CreateFromConnectionString(connectionString)
.CreateMessageReceiver(isDeadLetter
? QueueClient.FormatDeadLetterPath(queuePath)
: queuePath);
}
/// <summary>
/// Create a new <see cref="MessageReceiver"/> object using the specified Service Bus Topic Subscription path.
/// </summary>
/// <param name="connectionString">The connection string to access the desired service namespace.</param>
/// <param name="topicPath">The Service Bus Topic path.</param>
/// <param name="subscriptionName">The Service Bus Topic Subscription name.</param>
/// <param name="isDeadLetter">True if the desired path is the deadletter subqueue.</param>
public static MessageReceiver CreateMessageReceiver(string connectionString, string topicPath,
string subscriptionName, bool isDeadLetter = false)
{
return MessagingFactory.CreateFromConnectionString(connectionString)
.CreateMessageReceiver(isDeadLetter
? SubscriptionClient.FormatDeadLetterPath(topicPath, subscriptionName)
: SubscriptionClient.FormatSubscriptionPath(topicPath, subscriptionName));
}
答案 2 :(得分:3)
如果您使用的是Microsoft.Azure.ServiceBus
而不是Microsoft.ServiceBus
,则略有不同。
var deadQueuePath = EntityNameHelper.FormatDeadLetterPath(your_queue_name);
var deadQueueReceiver = new MessageReceiver(connectionString, deadQueuePath);
根据EntityNameHelper
命名空间中的Microsoft.Azure.ServiceBus
类,对于主题,请使用订阅路径,而不要使用your_queue_name。
队列名称或订阅路径。
/// <summary>
/// Formats the dead letter path for either a queue, or a subscription.
/// </summary>
/// <param name="entityPath">The name of the queue, or path of the subscription.</param>
/// <returns>The path as a string of the dead letter entity.</returns>
public static string FormatDeadLetterPath(string entityPath)
{
return EntityNameHelper.FormatSubQueuePath(entityPath, EntityNameHelper.DeadLetterQueueName);
}
答案 3 :(得分:1)
使用最新的服务总线客户端库,您可以像这样访问死信队列。请注意在创建接收器时指定死信队列时跨语言的一致性:
const { ServiceBusClient } = require("@azure/service-bus");
const client = new ServiceBusClient("<connectionstring>");
const deadletterReceiver = client.createReceiver("queueName", { subQueueType: "deadLetter" });
const messages = await deadletterReceiver.receiveMessages(1);
if (messages.length > 0) {
console.log("Received the message from DLQ - ", messages[0].body);
// Mark message as complete, i.e. remove from DLQ
await deadletterReceiver.completeMessage(messages[0]);
} else {
console.log("Error: No messages were received from the DLQ.");
}
await deadletterReceiver.close();
import com.azure.messaging.servicebus.*;
import com.azure.messaging.servicebus.models.SubQueue;
ServiceBusReceiverClient deadletterReceiver = new ServiceBusClientBuilder()
.connectionString("<connectionstring>")
.receiver() // Use this for session or non-session enabled queue or topic/subscriptions
.queueName("queuename")
.subQueue(SubQueue.DEAD_LETTER_QUEUE)
.buildClient();
IterableStream<ServiceBusReceivedMessage> messages = receiver.receiveMessages(10);
messages.forEach(message -> {
System.out.printf("Id: %s. Contents: %s%n", message.getMessageId(),
message.getBody().toString());
//Remove message from DLQ
deadletterReceiver.complete(message);
});
deadletterReceiver.close();
import asyncio
from azure.servicebus import ServiceBusMessage, ServiceBusSubQueue
from azure.servicebus.aio import ServiceBusClient
servicebus_client = ServiceBusClient.from_connection_string(conn_str="<connectionstring>")
dlq_receiver = servicebus_client.get_queue_receiver(queue_name="queuename",
sub_queue=ServiceBusSubQueue.DEAD_LETTER)
async with dlq_receiver:
received_msgs = await dlq_receiver.receive_messages(max_message_count=10, max_wait_time=5)
for msg in received_msgs:
print(msg)
# remove the message from the DLQ
await dlq_receiver.complete_message(msg)
using Azure.Messaging.ServiceBus;
await using var client = new ServiceBusClient("<connectionstring>");
ServiceBusReceiver deadletterReceiver = client.CreateReceiver(
"queuename",
new ServiceBusReceiverOptions { SubQueue = SubQueue.DeadLetter }
);
ServiceBusReceivedMessage message = await deadletterReceiver.ReceiveMessageAsync();
if (message != null)
{
Console.WriteLine($"DeadLetter message = {message.Body}");
// remove the message from the DLQ
await deadletterReceiver.CompleteMessageAsync(message);
}
else
{
// DLQ was empty on last receive attempt
Console.WriteLine("Error: No messages were received from the DLQ.");
}
await deadletterReceiver.CloseAsync();
答案 4 :(得分:0)
那些想用python做的人。
从死信队列中接收消息:
from azure.servicebus import ServiceBusClient
import json
connectionString = "Your Connection String to Service Bus"
serviceBusClient = ServiceBusClient.from_connection_string(connectionString)
queueName = "Your Queue Name created in the Service Bus"
queueClient = serviceBusClient.get_queue(queueName)
with queueClient.get_deadletter_receiver(prefetch=5) as queueReceiver:
messages = queueReceiver.fetch_next(timeout=100)
for message in messages:
# message.body is a generator object. Use next() to get the body.
body = next(message.body)
message.complete()
希望对某人有帮助。