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);
}
Related
I am trying to connect to some mqtt public brokers for test, but I can't connect to any.
I tried to follow these instruction for the code: https://docs.emqx.com/en/cloud/latest/connect_to_deployments/c_sharp_sdk.html#connection
with error: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
I tried to connect to other public servers as broker.hivemq.com, mqtt.eclipse.org, test.mosquitto.org
But nothing seems to work. Did anyone succeed to connect to a public broker with c#?
I would highly appreciate any recommendations
using System;
using uPLibrary.Networking.M2Mqtt;
using uPLibrary.Networking.M2Mqtt.Messages;
namespace csharpMQTT
{
class Program
{
static MqttClient ConnectMQTT(string broker, int port, string clientId, string username, string password)
{
MqttClient client = new MqttClient(broker, port, false, MqttSslProtocols.None, null, null);
client.Connect(clientId, username, password);
if (client.IsConnected)
{
Console.WriteLine("Connected to MQTT Broker");
}
else
{
Console.WriteLine("Failed to connect");
}
return client;
}
static void Main(string[] args)
{
string broker = "broker.emqx.io";
int port = 1883;
string clientId = Guid.NewGuid().ToString();
string username = "emqx";
string password = "public";
MqttClient client = ConnectMQTT(broker, port, clientId, username, password);
}
}
}
Also, I tried to eliminate credentials:
using System;
using uPLibrary.Networking.M2Mqtt;
using uPLibrary.Networking.M2Mqtt.Messages;
namespace csharpMQTT
{
class Program
{
static MqttClient ConnectMQTT(string broker, int port, string clientId)
{
MqttClient client = new MqttClient(broker, port, false, MqttSslProtocols.None, null, null);
client.Connect(clientId);
if (client.IsConnected)
{
Console.WriteLine("Connected to MQTT Broker");
}
else
{
Console.WriteLine("Failed to connect");
}
return client;
}
static void Main(string[] args)
{
string broker = "broker.hivemq.com";
int port = 1883;
string clientId = Guid.NewGuid().ToString();
MqttClient client = ConnectMQTT(broker, port, clientId);
}
}
}
I used target framework for project : .Net Core 3.1 and nuget package M2Mqtt 4.3.0
Considering that openvpn is a udp server running on port 1194, I am intrested to see , how can I send a packet using udp c#.
I am aware of the fact that openVpn is a protocol itself, and considering the lack of knowledge in that domain , I started writing a simple udp client to send a message to server.
Here is the code.
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace ConnectOpenVPN
{
public struct Received
{
public IPEndPoint Sender;
public string Message;
}
abstract class UdpBase
{
protected UdpClient Client;
protected UdpBase()
{
Client = new UdpClient();
}
public async Task<Received> Receive()
{
var result = await Client.ReceiveAsync();
return new Received()
{
Message = Encoding.ASCII.GetString(result.Buffer, 0, result.Buffer.Length),
Sender = result.RemoteEndPoint
};
}
}
//Client
class UdpUser : UdpBase
{
private UdpUser() { }
public static UdpUser ConnectTo(IPAddress serverIP, int port)
{
var connection = new UdpUser();
connection.Client.Connect(serverIP, port);
return connection;
}
public void Send(string message)
{
var datagram = Encoding.ASCII.GetBytes(message);
Client.Send(datagram, datagram.Length);
}
}
class Program
{
static void Main(string[] args)
{
//create a new client
var client = UdpUser.ConnectTo(IPAddress.Parse("13.23.118.17"), 1194);
Task.Run(async () => {
while (true)
{
try
{
var received = await client.Receive();
Console.WriteLine(received.Message);
if (received.Message.Contains("quit"))
break;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.ReadLine();
}
}
});
string read;
do
{
read = Console.ReadLine();
client.Send(read);
} while (read != "quit");
}
}
}
So , I am unable to recieve any message from server and just witing for ever. Not even an denied or exception.
I was planning to send credentials and openvpn config next.
What are the thing I should do when creating client program for open vpn client ? Is creating an UDP client even correct or I should be using openVPn protocol itseld and how?
I have a microservice (Web API) within an eventdriven architecture receiving messages from RabbitMQ and it is supposed to save them into a PostgreSQL DB using ADO.NET.
Unfortunately, my connection pool (currently set to 50) gets exhausted quite fast, giving me this error message:
The connection pool has been exhausted, either raise MaxPoolSize
My RabbitMQ Consumer is set up like this (Singleton):
public class Listener : RabbitMqConnection
{
public AsyncEventingBasicConsumer _asyncConsumer;
private static readonly SemaphoreSlim AsyncLock = new SemaphoreSlim(1, 1);
public Listener()
{
_asyncConsumer = new AsyncEventingBasicConsumer(_channel);
_asyncConsumer.Received += ConsumerReceived;
}
public async Task ConsumerReceived(object sender, BasicDeliverEventArgs message)
{
await AsyncLock.WaitAsync();
try
{
//Performing logic and saving into database
//....
using (var ctx = ContextFactory.GetContext<PostgreSqlDatabaseContext>(_connectionString))
{
//Creating query with StringBuilder...
await ctx.Database.ExecuteSqlCommandAsync(query.ToString(), parameters);
}
_channel.BasicAck(message.DeliveryTag, false);
}
catch (DecoderFallbackException decoderFallbackException)
{
_logger.LogError($"...");
_channel.BasicNack(message.DeliveryTag, false, false);
}
finally {
AsyncLock.Release();
}
}
}
ContextFactory
internal class ContextFactory
{
public static T GetContext<T>(string sqlConnection) where T : DbContext
{
var optionsBuilder = new DbContextOptionsBuilder<PostgreSqlDatabaseContext>();
optionsBuilder.UseNpgsql(sqlConnection);
return new PostgreSqlDatabaseContext(optionsBuilder.Options) as T;
}
}
RabbitMqConnection:
public abstract class RabbitMQConnection
{
public IModel _channel;
public IBasicProperties _properties;
public AsyncEventingBasicConsumer _asyncConsumer;
public ConnectionFactory _factory;
public ConnectConfiguration _connectConfiguration;
bool isConnected = false;
public void Connect(ConnectConfiguration connectConfiguration)
{
if (!isConnected)
{
_connectConfiguration = connectConfiguration;
CreateFactory(_connectConfiguration);
SetupConfiguration(_connectConfiguration.Exchange);
}
}
private void CreateFactory(ConnectConfiguration config)
{
_factory = new ConnectionFactory
{
AutomaticRecoveryEnabled = true,
DispatchConsumersAsync = true,
UseBackgroundThreadsForIO = true,
RequestedHeartbeat = 15,
HostName = config.Server,
UserName = config.UserName,
Password = config.Password
};
if (!string.IsNullOrWhiteSpace(config.Vhost))
_factory.VirtualHost = config.Vhost;
}
private void SetupConfiguration(string exchange)
{
var connection = _factory.CreateConnection();
_channel = connection.CreateModel();
_properties = _channel.CreateBasicProperties();
_properties.Persistent = true;
_channel.BasicQos(0, 10, false);
_channel.ExchangeDeclare(exchange, "topic", true);
isConnected = true;
}
}
I can´t not understand why I keep getting this error. Isn´t the SemaphoreSlim with WaitAsync() and Release() suppose to prevent the ConsumerReceived method from running the logic?
I have a following problem: creation client to web service takes too long. I have web service SOAP which I import to Xamarin Forms PCL as service reference. I create client in static class and with Tasks and Asyncs methods. Here is my code:
using System;
using System.ServiceModel;
using System.Threading.Tasks;
using MyApp.WebService;
public static class Client
{
public static ServiceClient Connection;
private const string UserName = "admin";
private const string Password = "password";
private static string _username;
private static string _password;
private static string _serviceAddress;
private static void Login()
{
var binding = new BasicHttpBinding
{
SendTimeout = TimeSpan.FromSeconds(10000),
Security =
{
Mode = BasicHttpSecurityMode.TransportCredentialOnly,
Transport = {ClientCredentialType = HttpClientCredentialType.Basic}
},
MaxReceivedMessageSize = 1024 * 10,
AllowCookies = true
};
Connection = new ServiceClient(binding, new EndpointAddress(_serviceAddress)); // takes around 12 seconds, i don't know what's going so long
Connection.ClientCredentials.UserName.UserName = UserName;
Connection.ClientCredentials.UserName.Password = Password;
Connection.OpenAsync();
Connection.UserAuthorisationCompleted += UserAuthorisationCompleted;
Connection.UserAuthorisationAsync(_username, _password);
}
private static void UserAuthorisationCompleted(object sender, UserAuthorisationCompletedEventArgs e)
{
// here I checking result - at the moment it's doesn't matter
}
public static Task LoginAsync(string username, string password, string serviceAddress)
{
_username = username;
_password = password;
_serviceAddress = serviceAddress;
var task = new Task(Login);
task.Start();
return task;
}
}
Does anyone know why it takes so long? On the server nothing is at this point.
I have been trying to read emails from a web mail version of a client email. Searched a lot in the internet. I was using a code I found online
using System.Collections.Generic;
using System.Linq;
using ActiveUp.Net.Mail;
using System;
namespace GmailReadImapEmail
{
public class MailRepository {
private Imap4Client client;
public MailRepository(string mailServer, int port, bool ssl, string login, string password) {
if (ssl)
Client.ConnectSsl(mailServer, port);
else
Client.Connect(mailServer, port);
Client.Login(login, password);
}
public IEnumerable<Message> GetAllMails(string mailBox) {
return GetMails(mailBox, "ALL").Cast < Message > ();
}
public IEnumerable<Message> GetUnreadMails(string mailBox) {
return GetMails(mailBox, "UNSEEN").Cast < Message > ();
}
protected Imap4Client Client
{
get {
return client ??(client = new Imap4Client());
}
}
private MessageCollection GetMails(string mailBox, string searchPhrase) {
Mailbox mails = Client.SelectMailbox(mailBox);
MessageCollection messages = mails.SearchParse(searchPhrase);
return messages;
}
public static void Main() {
var mailRepository = new MailRepository(
"outlook.office365.com",
143,
true,
"username",
"password"
);
var emailList = mailRepository.GetAllMails("inbox");
foreach(Message email in emailList)
{
Console.WriteLine("<p>{0}: {1}</p><p>{2}</p>", email.From, email.Subject, email.BodyHtml.Text);
if (email.Attachments.Count > 0) {
foreach(MimePart attachment in email.Attachments)
{
Console.WriteLine("<p>Attachment: {0} {1}</p>", attachment.ContentName, attachment.ContentType.MimeType);
}
}
}
}
}
}
I am getiing an exception in Client.ConnectSsl(mailserver,port)
The exception is : No connection could be made because the target machine actively refused it