C# Azure服务总线客户端连接持久性

C# Azure服务总线客户端连接持久性,c#,azure,client,azureservicebus,C#,Azure,Client,Azureservicebus,下面我有一个围绕Azure服务总线代码的基本包装器,我们将在工作者角色中使用该代码。每次运行worker角色时,都会实例化此ServiceBusClient;然后用于访问队列,直到没有剩余项可供枚举为止 public class ServiceBusClient : IDisposable, IServiceBusClient { private const int DEFAULT_WAIT_TIME_IN_SECONDS = 120; private const string

下面我有一个围绕Azure服务总线代码的基本包装器,我们将在工作者角色中使用该代码。每次运行worker角色时,都会实例化此
ServiceBusClient
;然后用于访问队列,直到没有剩余项可供枚举为止

public class ServiceBusClient : IDisposable, IServiceBusClient
{
    private const int DEFAULT_WAIT_TIME_IN_SECONDS = 120;

    private const string SERVICE_BUS_CONNECTION_STRING_KEY = "service.bus.connection.string";

    private readonly MessagingFactory _messagingFactory;

    private readonly NamespaceManager _namespaceManager;

    private readonly QueueClient _queueClient;

    private readonly ISettingsManager _settingsManager;

    public ServiceBusClient(ISettingsManager settingsManager, string queueName)
    {
        _settingsManager = settingsManager;

        var connectionString = _settingsManager.GetSetting<string>(SERVICE_BUS_CONNECTION_STRING_KEY);

        _namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString);
        _messagingFactory = MessagingFactory.CreateFromConnectionString(connectionString);

        _queueClient = GetOrCreateQueue(queueName);
    }

    public void Dispose()
    {
        _messagingFactory.Close();
    }

    public BrokeredMessage ReceiveTopMessage()
    {
        return _queueClient.Receive(TimeSpan.FromSeconds(DEFAULT_WAIT_TIME_IN_SECONDS));
    }

    public void SendMessage(object bodyObject)
    {
        var message = new BrokeredMessage(bodyObject);

        _queueClient.Send(message);
    }

    private QueueClient GetOrCreateQueue(string queueName)
    {
        var queue = !_namespaceManager.QueueExists(queueName)
                        ? _namespaceManager.CreateQueue(queueName)
                        : _namespaceManager.GetQueue(queueName);

        return _messagingFactory.CreateQueueClient(queue.Path, ReceiveMode.PeekLock);
    }

}
公共类ServiceBusClient:IDisposable,IServiceBusClient
{
private const int DEFAULT_WAIT_TIME_IN_SECONDS=120;
private const string SERVICE\u BUS\u CONNECTION\u string\u KEY=“SERVICE.BUS.CONNECTION.string”;
私有只读MessagingFactory\u MessagingFactory;
私有只读命名空间管理器_NamespaceManager;
专用只读队列客户端_QueueClient;
私有只读ISettingsManager _settingsManager;
公共ServiceBusClient(ISettingsManager设置sManager,字符串queueName)
{
_settingsManager=settingsManager;
var connectionString=\u settingsManager.GetSetting(服务\u总线\u连接\u字符串\u键);
_namespaceManager=namespaceManager.CreateFromConnectionString(connectionString);
_messagingFactory=messagingFactory.CreateFromConnectionString(connectionString);
_queueClient=GetOrCreateQueue(queueName);
}
公共空间处置()
{
_messagingFactory.Close();
}
公共代理消息ReceiveTopMessage()
{
返回_queueClient.Receive(TimeSpan.FromSeconds(默认的等待时间,单位为秒));
}
公共无效发送消息(对象bodyObject)
{
var消息=新代理消息(bodyObject);
_queueClient.Send(message);
}
private QueueClient GetOrCreateQueue(字符串queueName)
{
var queue=!\u namespaceManager.QueueExists(queueName)
?_namespaceManager.CreateQueue(queueName)
:_namespaceManager.GetQueue(queueName);
返回_messagingFactory.CreateQueueClient(queue.Path,ReceiveMode.PeekLock);
}
}
正如您所看到的,我在构造函数中初始化了
NamespaceManager
MessagingFactory
QueueClient
:然后在调用
SendMessage()
ReceiveTopMessage()
时重用它们,并使用
Dispose()
方法关闭连接

我的问题是我使用的方法是否安全;当工作者角色枚举队列上的所有消息时,保持
队列客户端的单个实例
处于打开状态(该进程可以在调用
ReceiveTopMessage()
之间长时间等待的情况下使连接保持打开状态)是否会持续工作,而不会出现暂时性问题,或者每次打开和关闭连接是否谨慎

作为旁白;如何在Microsoft服务总线代码中执行瞬时故障处理?它是默认执行的还是我们需要实现?

使用由用于创建它的MessagingFactory对象管理的连接。建议对多个请求重用同一客户机对象。如以下文件所述:

服务总线使客户端能够通过两个端口发送和接收消息 协议:服务总线客户端协议和HTTP。服务车 客户端协议更有效,因为它维护连接 只要消息工厂存在,就发送到服务总线服务。信息技术 还实现批处理和预取。服务总线客户端 协议可用于使用.NET托管的.NET应用程序 应用程序编程接口。 (...) 服务总线客户端对象(如QueueClient或MessageSender)是 通过MessagingFactory对象创建,该对象还提供 连接的内部管理。您不应该关闭邮件 工厂或队列、主题和订阅客户端 消息,然后在发送下一条消息时重新创建它们。 关闭消息传递工厂将删除与服务总线的连接 服务,并在重新创建时建立新连接 工厂。建立连接是一项昂贵的操作,可能会 可通过在以下情况下重复使用相同的工厂和客户机对象来避免 多个操作。 (...) 由创建的所有客户端(除接收方之外的发送方) 同一工厂共享一个TCP连接

关于瞬时故障处理,
QueueClient
具有一个用于确定是否应重试请求的。还有一个替代瞬态故障处理框架的


关于消息接收循环,中有指导。微软已经意识到很难实现一个写得好、弹性好的消息接收循环,所以他们引入了作为替代方案。

非常好的链接,谢谢;我将在我们的包装中使用。如果
QueueClient
类未打开连接;当使用
.Receive()之类的方法时,是否会自动处理此问题
被调用?我已经用关于推荐使用模式和哪个对象处理TCP连接的其他文档澄清了我的答案。我的问题与这个问题相关,如果您能看一看,我将不胜感激:@FernandoCorrieado您仍然认为我们应该。CloseAsync()当我们向Microsoft.ServiceBus.Net Standart兼容NuGet软件包上的队列或主题发送消息时?