C# ASP.NET中长时间运行的RabbitMQ连接

C# ASP.NET中长时间运行的RabbitMQ连接,c#,asp.net,iis,rabbitmq,C#,Asp.net,Iis,Rabbitmq,我知道建立RabbitMQ连接的成本很高,所以当我想将消息放入队列时,不建议使用{connect/publish/disconnect}。但是,我找不到一种方法来跨多个请求建立长时间运行的RabbitMQ连接 我想要实现的是,在我的ASP.NET应用程序中,只有一个(或有限的)RabbitMQ连接在IIS上运行,并将其用于不同的请求,而不是为每个请求创建不同的连接 下面的代码是我现在所拥有的。我需要以某种方式删除这些using语句并保持连接打开 非常感谢 public ReturnCode At

我知道建立RabbitMQ连接的成本很高,所以当我想将消息放入队列时,不建议使用{connect/publish/disconnect}。但是,我找不到一种方法来跨多个请求建立长时间运行的RabbitMQ连接

我想要实现的是,在我的ASP.NET应用程序中,只有一个(或有限的)RabbitMQ连接在IIS上运行,并将其用于不同的请求,而不是为每个请求创建不同的连接

下面的代码是我现在所拥有的。我需要以某种方式删除这些using语句并保持连接打开

非常感谢

public ReturnCode AtomicPublish(string userName, string password, string virtualHost, string hostName, string exchangeName, string queueName, string message)
{
    using (IConnection conn = new ConnectionFactory()
    {
        UserName = userName,
        Password = password,
        VirtualHost = virtualHost,
        HostName = hostName
    }.CreateConnection())
    {
        using (IModel model = conn.CreateModel())
        {
            model.ExchangeDeclare(exchangeName, ExchangeType.Fanout, true);
            model.QueueDeclare(queueName, true, false, false, null);
            model.QueueBind(queueName, exchangeName, "", null);
            byte[] messageBodyBytes = System.Text.Encoding.UTF8.GetBytes(message);
            model.BasicPublish(exchangeName, string.Empty, null, messageBodyBytes);
        }
    }
    return ReturnCode.OK;
}

从我的头顶上

private static IConnection _connection {get;set;}
private static object LockObject = new object();
private static IConnection GetConnection (string username, string password, string virtualHost, string hostName)
    get{
        // do work here in case the connection is closed as well.
        if (_connection == null){
            lock(LockObject){
                if (_connection == null){
                    _connection = new ConnectionFactory
                       {
                           UserName = userName,
                           Password = password,
                           VirtualHost = virtualHost,
                           HostName = hostName

                       }.CreateConnection();
                }
            }

        }
        return _connection;
    }
}

public ReturnCode AtomicPublish(string userName, string password, string virtualHost, string hostName, string exchangeName, string queueName, string message)
{

        using (IModel model = GetConnection(userName, password, virtualHost, hostName).CreateModel()) //lazy loads the get connection
        {
            model.ExchangeDeclare(exchangeName, ExchangeType.Fanout, true);
            model.QueueDeclare(queueName, true, false, false, null);
            model.QueueBind(queueName, exchangeName, "", null);

            byte[] messageBodyBytes = System.Text.Encoding.UTF8.GetBytes(message);
            model.BasicPublish(exchangeName, string.Empty, null, messageBodyBytes);
        }

    return ReturnCode.OK;
}

变量连接应使用服务器端存储

如果同一用户的所有请求的连接相同,请将其保存在ASP.NET的会话对象中

如果对所有用户相同,则将其保存在缓存应用程序对象中


然后,当您需要再次加载并重新使用它时,从会话或缓存中取回它,请参见下面的示例:

正如您所说,建立RabbitMQ连接非常昂贵,因此当您打开连接时,不应发送消息并断开连接。 事实上,RabbitMQ基于protocole AMQP,该协议允许向不同主题的多个接收者发送许多消息(而不是使用队列),这意味着每个接收者都在收听不同的主题,如以下示例:

using System;
using System.Linq;
using RabbitMQ.Client;
using System.Text;
class EmitLogTopic
{
public static void Main(string[] args)
{
    var factory = new ConnectionFactory() { HostName = "localhost" };
    using(var connection = factory.CreateConnection())
    using(var channel = connection.CreateModel())
    {
        channel.ExchangeDeclare(exchange: "topic_logs",
                                type: "topic");

        var routingKey = (args.Length > 0) ? args[0] : "anonymous.info";
        var message = (args.Length > 1)
                      ? string.Join(" ", args.Skip( 1 ).ToArray())
                      : "Hello World!";
        var body = Encoding.UTF8.GetBytes(message);
        channel.BasicPublish(exchange: "topic_logs",
                             routingKey: routingKey,
                             basicProperties: null,
                             body: body);
        Console.WriteLine(" [x] Sent '{0}':'{1}'", routingKey, message);
    }
}
}

本教程提供了更多信息。

也许,您应该将ConnectionFactory作为依赖项接收?在这种情况下,您将能够将其实例化为Singleton,并且无需每次都创建它time@DenysProdan这里的问题源于asp.net应用程序的生命周期。请求是在不同的线程中处理的,所以我应该做一些事情来确保我的连接没有被处理(即使它来自一个单实例),正如Davide Piras所说,应用程序缓存看起来是最好的选择。很遗憾,这不是我问题的答案。对于控制台应用程序,维护长时间运行的rabbitmq连接并在需要时使用它是非常清楚的。这些示例通常也是控制台应用程序。问题是,我需要找到一种在ASP.NET应用程序中保持连接打开的方法。它的生命周期与控制台应用程序截然不同。