0

The RabbitMQ Server is giving me the message: Missed heartbeats from client. I know this message occour when the cliente stop sending the heartbeat to server, then RabbitMq server close the connection. The problem is that I'm using RabbitMq in localhost, so I think it isn't about network blocking. My client uses the EasyNetQ(.Net 4.6.1 / Component Version: 6.3.1) component and it should had handled this heartbeat by itself.

Why the client wouldn't send the heartbeat even I'm using RabbitMq in localhost?

Bellow an example from my code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using EasyNetQ;
using EasyNetQ.Topology;
using InteraxaFramework.Genesys.Common;
using log4net;


namespace Bridge.Genesys.Services
{
    public class RabbitProducer
    {
        private string _hostName;
        private int _port;
        private string _userName;
        private string _password;
        private IConnection _connection;
        private IModel _channel;
        private int _timeout;
        private IBus bus;
        private MessageProperties _msgProperties;
        private Dictionary<string, Exchange> _exchages;

        public RabbitProducer(string hostName, int port, string userName, string password, int timeout = 60)
        {
            _hostName = hostName;
            _port = port;
            _userName = userName;
            _password = password;
            _timeout = timeout;
            createConnection();
            _msgProperties = new MessageProperties();
            _exchages = new Dictionary<string, Exchange>();
        }

        private Exchange GetExchange(string exchange)
        {
            if (!_exchages.ContainsKey(exchange))
            {
                _exchages[exchange] = new Exchange(exchange);
            }

            return _exchages[exchange];
        }

        private void createConnection()
        {

            if (bus == null)
            {
                bus = RabbitHutch.CreateBus($"host={_hostName}:{_port};username={_userName};password={_password};timeout={_timeout}");
            }
        }

        public async Task PublishExchangeAsync(string exchange, byte[] body)
        {

            await bus.Advanced.PublishAsync(
                    GetExchange(exchange),
                    string.Empty,
                    false,
                   _msgProperties,
                   body);

        }

        public void Disconnect()
        {
            if (_exchages != null)
            {
                _exchages.Clear();
            }

            if (bus != null)
            {
                bus.Dispose();
            }
        }
    }
}

Other parts of my code uses this class as singleton. The program is a windows service that keeps always running and uses just one connection and one channel during the service lifetime.

The creation of singleton object:

this.rabbitProducer = new RabbitProducer("localhost", 5672, "guest", "guest", 60);

The utilization of the publisher:

var bf = new BinaryFormatter();
using (var ms = new MemoryStream())
{
   bf.Serialize(ms, JsonObj);
   var bytes = ms.ToArray();
   var bodyBytes = bytes;
   await rabbitProducer.PublishExchangeAsync(queueName, bodyBytes);
}
Ivan Muniz
  • 19
  • 4
  • is it a typo "localhos" instead of "localhost"? can you connect in browser and login using the same credentials? – Netferret May 20 '22 at 13:45
  • 1
    Sorry, @Netferret! I typed incorrectly in this example, but is ok in my project. Using in browse I can connect normally. Actually, the progam is cappable to publish normally untill receive this timeout from rabbitmq in some part of the day. – Ivan Muniz May 20 '22 at 14:08
  • No worries, This is usually the way I use rabbitmq. https://www.rabbitmq.com/dotnet-api-guide.html#publishing Not familar with that library, but looking at basic publish form what they have on their website. https://github.com/EasyNetQ/EasyNetQ/wiki/Publish var message = new MyMessage { Text = "Hello Rabbit" }; await bus.PubSub.PublishAsync(message).ConfigureAwait(false); It looks like that should be sufficient, you would need to check that that ports, exchange etc are all correct though for that bus/pubsub object. So maybe breakpoint them and take a good look when it runs. – Netferret May 20 '22 at 14:22
  • 2
    I did some research at rabbitmq installation environment and find out that the installation is clustered, with two nodes. When I remove one node from the cluster, the problem stops. I changed the queues to quorum, but it not did any effect. I will try to change the log level of rabbitmq server to see if I can get more details. – Ivan Muniz May 30 '22 at 18:55
  • @IvanMuniz Did you find a solution? We seem to be facing a similar problem. – Oleksii Z Nov 08 '22 at 08:20
  • @AI Z, I solved the problem after adding some logs in my application. I could see in the logs that the events were not arriving at the publisher method when the amount of events where large. Then I did a code review and discovered that one of the methods that calls the publisher was setted as async, but it didin't have any tasks to be awaited in his body. So one call wasn't fineshed when other has started. I removed the async and it worked for me. – Ivan Muniz Nov 09 '22 at 12:36

0 Answers0