Могу ли я удалить сообщение из очереди ActiveMQ в коде C#?
Я хочу установить уникальный guid для каждого сообщения в заголовке сообщения, затем, если я хочу, я могу удалить конкретное сообщение, если я хочу. Есть ли API в NMS, которые могут помочь мне удалить сообщение? Я использую ActiveMQ 5.9.0 и NMS 1.6.1
1 ответ
Очень возможно выполнить отдельное удаление из библиотеки C# и NMS напрямую без REST API.
Я использую NMS 18.0 от NuGet в проекте C# для нашего инструмента поддержки и обслуживания Nodinite, и это код одного из многих агентов мониторинга, в данном случае для ActiveMQ. Этот код используется для удаления индивидуально выбранных сообщений.
Этот код удаляет 1 сообщение (messageId) из очереди (queueName)
internal static void DeleteMessageFromQueue(ActiveMQOption activeMQOption, string queueName, string messageId)
{
IConnectionFactory factory = CreateConnectionFactory(activeMQOption);
using (IConnection connection = factory.CreateConnection())
{
using (ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))
{
using (IDestination destination = session.GetQueue(queueName))
{
using (IMessageConsumer consumer = session.CreateConsumer(destination, $"JMSMessageID LIKE '%{messageId}%'"))
{
connection.Start();
var message = consumer.Receive(new TimeSpan(0, 0, 1));
consumer.Close();
connection.Close();
if (message == null)
{
throw new Exception($"Message '{messageId}' not found on queue '{queueName}'");
}
}
}
}
}
}
Вспомогательный метод для создания фабрики (с использованием простой модели класса C#, которую вам нужно заменить своим собственным кодом, но пример должен быть достаточно простым, чтобы следовать)
public static Apache.NMS.ActiveMQ.ConnectionFactory CreateConnectionFactory(ActiveMQOption activeMQOption)
{
Uri connecturi = new Uri(activeMQOption.ConnectionString);
Apache.NMS.ActiveMQ.ConnectionFactory factory = new Apache.NMS.ActiveMQ.ConnectionFactory(connecturi);
if (activeMQOption.UseAuthentication)
{
factory.UserName = activeMQOption.User;
factory.Password = activeMQOption.Password;
}
return factory;
}
Да, хотя только в том случае, если у этого пункта назначения нет активных потребителей. Вы можете сделать что-то вроде этого:
protected static void DeleteDestination()
{
IConnectionFactory factory = new ConnectionFactory(ReplaceEnvVar(connectionURI));
using (Connection connection = factory.CreateConnection() as Connection)
{
using (ISession session = connection.CreateSession())
{
IQueue queue = session.GetQueue(testQueueName);
try
{
connection.DeleteDestination(queue);
}
catch
{
}
}
}
}