2013-02-22 6 views
8

Se sono connesso a RabbitMQ e ascolto eventi utilizzando un EventingBasicConsumer, come posso sapere se sono stato disconnesso dal server?Come può un client RabbitMQ dire quando perde la connessione al server?

So che c'è un evento di arresto, ma non si attiva se scollego il cavo di rete per simulare un guasto.

Ho anche provato l'evento ModelShutdown e CallbackException sul modello, ma nessuno sembra funzionare.

MODIFICA ----- Quello che ho contrassegnato come risposta è corretto, ma era solo una parte della soluzione per me. C'è anche una funzionalità di HeartBeat incorporata in RabbitMQ. Il server lo specifica nel file di configurazione. Il valore predefinito è 10 minuti, ma ovviamente è possibile cambiarlo.

Il client può anche richiedere un intervallo diverso per l'heartbeat impostando il valore RequestedHeartbeat sull'istanza ConnectionFactory.

+0

È possibile aggiungere un heartbeat alla connessione che rileverà l'interruzione del servizio – robthewolf

+0

È possibile pubblicare l'intero codice? Sto affrontando lo stesso problema. Grazie in anticipo. – Pritam

+0

Hai davvero bisogno di 3 cose. 1 ConnectionFactory deve impostare un RequestedHeartBeat. 2 dopo aver creato una connessione, definire l'evento ConnectionShutdown come descritto nella risposta contrassegnata. 3 assicurati di averlo configurato correttamente nel file di configurazione di rabbitmq. (scusa non ho questa parte in giro al momento). Vedrò se riesco a estrarre il codice senza alcuna specifica implementazione. – Kelly

risposta

5

Immagino che tu stia utilizzando la libreria C#? (ma anche così penso che gli altri abbiano un evento simile).

è possibile effettuare le seguenti operazioni:

public class MyRabbitConsumer 
{ 
    private IConnection connection; 

    public void Connect() 
    { 
    connection = CreateAndOpenConnection(); 
    connection.ConnectionShutdown += connection_ConnectionShutdown; 
    } 

    public IConnection CreateAndOpenConnection() { ... } 

    private void connection_ConnectionShutdown(IConnection connection, ShutdownEventArgs reason) 
    { 

    } 
} 
+0

Dove devo implementare questo codice? – Pritam

0

Questo è un esempio di esso, ma la risposta contrassegnato è quello che mi ha portato a questo.

var factory = new ConnectionFactory 
{ 
    HostName = "MY_HOST_NAME", 
    UserName = "USERNAME", 
    Password = "PASSWORD", 
    RequestedHeartbeat = 30 
}; 

using (var connection = factory.CreateConnection()) 
{ 
    connection.ConnectionShutdown += (o, e) => 
    {      
     //handle disconnect        
    }; 

    using (var model = connection.CreateModel()) 
    { 
     model.ExchangeDeclare(EXCHANGE_NAME, "topic"); 
     var queueName = model.QueueDeclare(); 

     model.QueueBind(queueName, EXCHANGE_NAME, "#"); 

     var consumer = new QueueingBasicConsumer(model); 
     model.BasicConsume(queueName, true, consumer); 

     while (!stop) 
     { 
      BasicDeliverEventArgs args;      
      consumer.Queue.Dequeue(5000, out args); 

      if (stop) return; 

      if (args == null) continue; 
      if (args.Body.Length == 0) continue; 

      Task.Factory.StartNew(() => 
      { 
       //Do work here on different thread then this one 
      }, TaskCreationOptions.PreferFairness); 
     } 
    } 
} 

Alcune cose da notare su questo.

Sto usando # per l'argomento. Questo prende tutto. Di solito vuoi limitare un argomento.

Sto impostando una variabile chiamata "stop" per determinare quando il processo dovrebbe terminare. Noterai che il ciclo gira per sempre fino a quando quella variabile è vera.

Il Dequeue attende 5 secondi quindi esce senza ricevere dati se non c'è un nuovo messaggio. Questo per garantire che ascoltiamo quella variabile di stop e in realtà smettiamo ad un certo punto. Cambia il valore a tuo piacimento.

Quando arriva un messaggio sposto il codice di gestione su una nuova discussione. Il thread corrente è riservato solo per ascoltare i messaggi di rabbitmq e se un gestore impiega troppo tempo per elaborare non voglio rallentare gli altri messaggi. Potrebbe essere necessario o meno a seconda della tua implementazione. Fai attenzione però a scrivere il codice per gestire i messaggi. Se è necessario un minuto per eseguire e ricevere i messaggi in tempi inferiori alla seconda, si esaurirà la memoria o almeno in gravi problemi di prestazioni.

Problemi correlati