¿Cómo obtengo el estado de conexión de Websphere MQ y cómo reinicio la conexión?
1.) Desde un cliente .net, ¿cómo compruebo si el cliente está conectado al servidor (es decir, puede enviar y recibir)? Sí, puedo enviar un mensaje dentro de un bloque de prueba y detectar la excepción que sigue, pero espero Una solución más elegante.
2) ¿Cómo abro, cierro y vuelvo a abrir conexiones? En mis intentos de resolver la pregunta 1 anterior, descubrí que si abro una conexión, llamo a la conexión. Cerrar () No puedo obtener otra conexión de la fábrica de conexiones (consulte el fragmento de código a continuación). Recibo el mensaje de error XMSCC0008
Estoy usando una configuración muy estándar de vainilla MQ. Aquí es cómo mi cliente se conecta:
ISession session = MQAccess.GetSession(MQAccess.Connection);
IDestination destination = session.CreateTopic(SubTopicName);
Consumer = MQAccess.GetConsumer(session, destination);
Consumer.MessageListener = new MessageListener(HandleMQSubEvent);
MQAccess.Connection.Start();
donde MQAccess es una pequeña clase de utilidad.
Edita la pregunta para agregar el código MQAccess:
public static class MQAccess
{
public static readonly MQConfigurationSectionHandler ConfigSettings;
public static readonly IConnectionFactory ConnectionFactory;
private static readonly IConnection connection;
public static IConnection Connection
{
get { return connection; }
}
static MQAccess()
{
ConfigSettings = (MQConfigurationSectionHandler)
ConfigurationManager.GetSection("mq-configuration");
XMSFactoryFactory factory = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ);
ConnectionFactory = factory.CreateConnectionFactory();
ConnectionFactory.SetStringProperty(XMSC.WMQ_HOST_NAME, ConfigSettings.Hostname);
ConnectionFactory.SetIntProperty(XMSC.WMQ_PORT, ConfigSettings.Port);
ConnectionFactory.SetStringProperty(XMSC.WMQ_CHANNEL, ConfigSettings.Channel);
if (ConfigSettings.QueueManager == string.Empty)
{
ConnectionFactory.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, "");
}
else
{
ConnectionFactory.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, ConfigSettings.QueueManager);
}
connection = GetConnection();
}
public static IConnection GetConnection()
{
return ConnectionFactory.CreateConnection();
}
public static ISession GetSession(IConnection connection)
{
return connection.CreateSession(false, AcknowledgeMode.AutoAcknowledge);
}
public static IMessageProducer GetProducer(ISession session, IDestination destination)
{
return session.CreateProducer(destination);
}
public static IMessageConsumer GetConsumer(ISession session, IDestination destination)
{
return session.CreateConsumer(destination);
}
public static void MQPub(string TopicURI, string message)
{
using (var session = GetSession(Connection))
{
using (var destination = session.CreateTopic(TopicURI))
{
using (var producer = GetProducer(session, destination))
{
producer.Send(session.CreateTextMessage(message));
}
}
}
}
public static void MQPub(string TopicURI, IEnumerable<string> messages)
{
using (var session = GetSession(Connection))
{
using (var destination = session.CreateTopic(TopicURI))
{
using (var producer = GetProducer(session, destination))
{
foreach (var message in messages)
{
producer.Send(session.CreateTextMessage(message));
}
}
}
}
}
}
Edición: se cambió el nombre de la clase MQAccess a MQClient. Hizo una clase de instancia por sugerencia de T Rob. El método de desconexión todavía falla con los mensajes de error listados arriba
public class MQClient : IDisposable
{
public MQConfigurationSectionHandler ConfigSettings { get; private set; }
public IConnectionFactory ConnectionFactory { get; private set; }
public IConnection Connection { get; private set; }
public IMessageConsumer Consumer { get; private set; }
public IMessageProducer Producer { get; private set; }
// Save sessions as fields for disposing and future subscription functionality
private ISession ProducerSession;
private ISession ConsumerSession;
public string SubTopicName { get; private set; }
public string PubTopicName { get; private set; }
public bool IsConnected { get; private set; }
public event Action<Exception> ConnectionError;
private Action<IMessage> IncomingMessageHandler;
public MQClient(string subTopicName, string pubTopicName, Action<IMessage> incomingMessageHandler)
{
// Dont put connect logic in the constructor. If we lose the connection we may need to connect again.
SubTopicName = subTopicName;
PubTopicName = pubTopicName;
IncomingMessageHandler = incomingMessageHandler;
}
public string Connect()
{
IsConnected = false;
string errorMsg = string.Empty;
ConfigSettings = (MQConfigurationSectionHandler)
ConfigurationManager.GetSection("mq-configuration");
XMSFactoryFactory factory = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ);
ConnectionFactory = factory.CreateConnectionFactory();
ConnectionFactory.SetStringProperty(XMSC.WMQ_HOST_NAME, ConfigSettings.Hostname);
ConnectionFactory.SetIntProperty(XMSC.WMQ_PORT, ConfigSettings.Port);
ConnectionFactory.SetStringProperty(XMSC.WMQ_CHANNEL, ConfigSettings.Channel);
if (ConfigSettings.QueueManager == string.Empty)
ConnectionFactory.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, "");
else
ConnectionFactory.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, ConfigSettings.QueueManager);
Connection = ConnectionFactory.CreateConnection();
if (!string.IsNullOrEmpty(PubTopicName))
{
ProducerSession = Connection.CreateSession(false, AcknowledgeMode.AutoAcknowledge);
Producer = ProducerSession.CreateProducer(ProducerSession.CreateTopic(PubTopicName));
}
if (!string.IsNullOrEmpty(SubTopicName) && IncomingMessageHandler != null)
{
ConsumerSession = Connection.CreateSession(false, AcknowledgeMode.AutoAcknowledge);
Consumer = ConsumerSession.CreateConsumer(ConsumerSession.CreateTopic(SubTopicName));
Consumer.MessageListener = new MessageListener(IncomingMessageHandler);
}
try
{
Connection.Start();
Connection.ExceptionListener = new ExceptionListener(ConnectionExceptionHandler);
IsConnected = true;
}
catch (TypeInitializationException ex)
{
errorMsg = "A TypeInitializationException error occured while attempting to connect to MQ. Check the Queue configuration in App.config. The error message is: " + ex.Message;
}
catch (IllegalStateException ex)
{
errorMsg = "An IllegalStateException error occured while attempting to connect to MQ. Check the Queue configuration in App.config. The error message is: " + ex.Message;
}
return errorMsg;
}
public void Disconnect()
{
if (Producer != null)
{
Producer.Close();
Producer.Dispose();
Producer = null;
}
if (ProducerSession != null)
{
// Call Unsubscribe here if subscription is durable
ProducerSession.Close();
ProducerSession.Dispose();
ProducerSession = null;
}
if (Connection != null)
{
Connection.Stop();
//if (Connection.ExceptionListener != null)
// Connection.ExceptionListener = null;
// Per Shashi............
//if (Consumer.MessageListener != null)
// Consumer.MessageListener = null;
Connection.Close();
Connection.Dispose();
Connection = null;
}
if (Consumer != null)
{
if (Consumer.MessageListener != null)
Consumer.MessageListener = null;
Consumer.Close();
Consumer.Dispose();
Consumer = null;
}
if (ConsumerSession != null)
{
// Call Unsubscribe here if subscription is durable
ConsumerSession.Close();
ConsumerSession.Dispose();
ConsumerSession = null;
}
IsConnected = false;
}
public void Publish(string message)
{
Producer.Send(ProducerSession.CreateTextMessage(message));
}
public void Publish(string[] messages)
{
foreach (string msg in messages)
Publish(msg);
}
public void ConnectionExceptionHandler(Exception ex)
{
Disconnect(); // Clean up
if (ConnectionError != null)
ConnectionError(ex);
}
#region IDisposable Members
private bool disposed;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
Disconnect();
disposed = true;
}
}
#endregion
}