代码之家  ›  专栏  ›  技术社区  ›  Code_Worm

当发送方在队列中发送消息时,asp.net web应用程序(作为侦听器)中未激发RabbitMQ Consumer.Received事件

  •  0
  • Code_Worm  · 技术社区  · 6 年前

    我有两个ASP.Net应用程序服务器,我想使用rabbitMQ(或类似的队列工具,如redis pub/sub)使所有服务器上的内存缓存失效。

    当应用程序服务器清除自己的缓存并将消息发送到消息队列(由rabbitMQ声明),并且所有其他服务器都在侦听该队列(在本例中为缓存队列)时,场景很简单,当它们接收到消息时(通过Consumer.Received甚至handler),它们也会使自己的内存缓存失效。

    为此,我必须将侦听器放在web应用程序中(不能放在控制台应用程序或windows服务中),因为每个ASP.net web应用程序都有自己的内存缓存,只能从web应用程序本身内部(而不是外部)访问。

    我已经在一个静态类中编写了一个listen方法,这里是我的listen方法代码

       public static void Listen()
        {
            var factory = new ConnectionFactory() { HostName = "localhost" };
            using (var connection = factory.CreateConnection())
            using (var channel = connection.CreateModel())
            {
                channel.QueueDeclare(queue: "hello",
                                     durable: false,
                                     exclusive: false,
                                     autoDelete: false,
                                     arguments: null);
    
                var consumer = new EventingBasicConsumer(channel);
                consumer.Received += (model, ea) =>
                {
                    var body = ea.Body;
                    var message = Encoding.UTF8.GetString(body);
                   // cache invalidation goes here
                };
                channel.BasicConsume(queue: "hello",
                                     autoAck: true,
                                     consumer: consumer);
            }
        }
    

    Listen 方法 Application_Start global.asax中的方法

       protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            CacheNotifier.Listen();
        }
    

    但当我从另一台服务器向队列发送消息时 Consumer.Received 未激发以接收发送的消息。

    而当我把完全相同的 方法,并从Main方法调用它(listen方法) static void Main(string[] args)

    首先,我想知道为什么我的侦听器不在ASP.net web应用程序中工作,而是在控制台应用程序中工作,RabbitMQ的官方文档也只使用控制台应用程序

    任何帮助都将不胜感激

    2 回复  |  直到 6 年前
        1
  •  1
  •   André Leblanc    6 年前

    我确实尝试了你的路线,但遇到了很多问题,基本上没有侦听器因为asp.net生命周期请求工作而停留。

    最后,我将代码的接收方部分放入Windows服务中。当您收到该消息时,您可以调用另一个web服务或将数据写入数据库。。。

        2
  •  1
  •   bottlenecked    5 年前

    我有着完全相同的经历:在集成测试期间,一切都正常工作,但是当从另一个项目引用我的库代码(使用RabbitMQ客户机)时,消息从队列中被很好地使用(我在RabbitMQ管理员中查看图),但从未引发OnReceived回调。

    发生的情况是,在回调中,我使用的是运行时无法定位的程序集类型,它将抛出RabbitMQ客户端正在捕获的异常 https://github.com/rabbitmq/rabbitmq-dotnet-client/blob/master/projects/client/RabbitMQ.Client/src/client/impl/ConcurrentConsumerDispatcher.cs#L89 .

    因此,如果有其他人遇到这种情况,请确保您已将回调连接到您的频道,如下图所示,以了解发生了什么

    channel.CallbackException += (chann, args) =>
    {
       //check args.Exception for details
       ///...
    };
    
        3
  •  1
  •   Patrick Guimalan    4 年前

        4
  •  0
  •   Luke Bakken    6 年前

    首先,我想知道为什么我的听众不能在一个特定的环境中工作 官方文档显示,ASP.net web应用程序可在控制台应用程序中运行 RabbitMQ也只使用控制台应用程序

    这是一个与RabbitMQ.NET客户端无关的.NET和ASP.NET编程问题。我建议阅读 this StackOverflow thread this thread .