2011-07-12 2 views
3

J'ai deux applications, app1.cs et app2.cs (codes ci-dessous). De plus j'ai aussi une DLL que j'ai extraite de refer.cs (code ci-dessous). Quand je compile app1.cs (qui envoie un objet de mesure) Je reçois l'exception suivante:Erreur bizarre RabbitMQ et Sérialisation

Unhandled Exception: RabbitMQ.Client.Exceptions.OperationInterruptioedException 

Je ne vois pas comment la connexion est interrompue. Voyez-vous où le problème est causé?

Cordialement, Demi

//refer.cs from which refer.dll is created 

using System; 
using System.IO; 
using System.Collections.Generic; 
using System.Runtime.Serialization; 
using System.Runtime.Serialization.Formatters.Binary; 

namespace refer 
{ 
    //start alternate serialization 
    public static class AltSerialization 
    { 
     public static byte[] AltSerialize(Measurement m) 
     { 
     using (var ms = new MemoryStream()) 
      { 
       var bf = new BinaryFormatter(); 
       bf.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple; 
       bf.Serialize(ms, m); 
       return ms.GetBuffer(); 
      } 
     } 

     public static Measurement AltDeSerialize(byte[] seriM) 
     { 
     using (var stream = new MemoryStream(seriM)) 
      { 
       BinaryFormatter bf = new BinaryFormatter(); 
       bf.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple; 
       return (Measurement)bf.Deserialize(stream);   
      } 
     } 
    } 
    //end alternte serialization 

    [Serializable] //This attribute sets class to be serialized 
    public class Measurement : ISerializable 
    {    
     [NonSerialized] public int id; 
     public int time; //timestamp 
     public double value; 

     public Measurement() 
     { 
      id = 1; 
      time = 12; 
      value = 0.01; 
     } 

     public Measurement(int _id, int _time, double _value) 
     { 
      id = _id; 
      time = _time; 
      value = _value; 
     } 

     //Deserialization constructor 
     public Measurement(SerializationInfo info, StreamingContext ctxt) 
     { 
      //Assign the values from info to the approporiate properties 
      Console.WriteLine("DeSerialization construtor called."); 
      time = (int)info.GetValue("MeasurementTime", typeof(int)); 
      value = (double)info.GetValue("MeasurementValue", typeof(double)); 
     } 

     //Serialization function 
     public void GetObjectData(SerializationInfo info, StreamingContext ctxt) 
     { 
      // Custom name-value pair 
      // Values must be read with the same name they're written  
      info.AddValue("MeasurementTime", time); 
      info.AddValue("MeasurementValue", value); 
     } 
    } 
} 

//MB1.cs

using System; 
using System.IO; 
using System.Collections.Generic; 
using System.Runtime.Serialization; 
using System.Runtime.Serialization.Formatters.Binary; 
using RabbitMQ.Client; 
using RabbitMQ.Client.Events; 
using UtilityMeasurement; 

public interface IMessageBus 
{  
string MsgSys  // Property 1 
{ 
    get; 
    set; 
} 

void write (Measurement m1); 
Measurement read(); 
void publish(string queue); 
void subscribe(string queue); 
} 

public class Rabbit : IMessageBus 
{ 
// Implementation of methods for Rabbit class go here 
private List<string> publishQ = new List<string>(); 
private List<string> subscribeQ = new List<string>(); 


public void write (Measurement m1) 
{ 
    byte[] body = Measurement.AltSerialize(m1); 

    IConnection connection = factory.CreateConnection(); 
    IModel channel = connection.CreateModel(); 

    foreach (string queue in publishQ) 
    { 
     channel.BasicPublish("", queue, null, body); 
     Console.WriteLine("\n [x] Sent to queue {0}.", queue); 
    } 
} 

public void publish(string queueName) 
{  
    channel.QueueDeclare(queueName, true, false, false, null); //durable=true 
    publishQ.Add(queueName); //and, add it the list of queue names to publish to 
} 

public Measurement read() 
{ 
    QueueingBasicConsumer consumer = new QueueingBasicConsumer(channel); 
    foreach (string queue in subscribeQ) 
    { 
     channel.BasicConsume(queue, true, consumer); 
    } 
    System.Console.WriteLine(" [*] Waiting for messages." + 
          "To exit press CTRL+C"); 
    BasicDeliverEventArgs ea = 
     (BasicDeliverEventArgs)consumer.Queue.Dequeue(); 
    return Measurement.AltDeSerialize(ea.Body); 
} 

public void subscribe(string queueName) 
{ 
    channel.QueueDeclare(queueName, true, false, false, null); 
    subscribeQ.Add(queueName); 
} 

public static string MsgSysName; 
public string MsgSys 
{ 
    get 
    { 
     return MsgSysName; 
    } 
    set 
    { 
     MsgSysName = value; 
    } 
} 

public Rabbit(string _msgSys) //Constructor 
{ 
    ConnectionFactory factory = new ConnectionFactory(); 
    factory.HostName = "localhost"; 

    System.Console.WriteLine("\nMsgSys: RabbitMQ"); 
    MsgSys = _msgSys; 
} 
} 

public class Zmq : IMessageBus 
{ 
public void write (Measurement m1) 
{ 
    // 
} 
public Measurement read() 
{ 
    // 
    return null; 
} 
public void publish(string queue) 
{ 
// 
} 
public void subscribe(string queue) 
{ 
//  
} 

public static string MsgSysName; 
public string MsgSys 
{ 
    get 
    { 
     return MsgSysName; 
    } 
    set 
    { 
     MsgSysName = value; 
    } 
} 

// Implementation of methods for Zmq class go here 
public Zmq(string _msgSys) //Constructor 
{ 
    System.Console.WriteLine("ZMQ"); 
    MsgSys = _msgSys; 
} 
} 

public class MessageBusFactory 
{ 
public static IMessageBus GetMessageBus(string MsgSysName) 
{ 
    switch (MsgSysName) 
    { 
     case "Zmq": 
      return new Zmq(MsgSysName); 
     case "Rabbit": 
      return new Rabbit(MsgSysName); 
     default: 
      throw new ArgumentException("Messaging type " + 
       MsgSysName + " not supported."); 
    } 
} 
} 

public class MainClass 
{ 
    public static void Main() 
    { 
    //Asks for the message system 
    System.Console.WriteLine("\nEnter name of messageing system: "); 
    System.Console.WriteLine("Usage: [Rabbit] [Zmq]"); 
    string MsgSysName = (System.Console.ReadLine()).ToString(); 

    //Create a new Measurement message 
    Measurement m1 = new Measurement(2, 2345, 23.456); 

    //Declare an IMessageBus instance: 
    //Here, an object of the corresponding Message System 
     // (ex. Rabbit, Zmq, etc) is instantiated 
    IMessageBus obj1 = MessageBusFactory.GetMessageBus(MsgSysName); 

    System.Console.WriteLine("\nA {0} object is now created.", MsgSysName); 

    System.Console.WriteLine("With Test message:\n ID: {0}", m1.id); 
    System.Console.WriteLine(" Time: {0}", m1.time); 
    System.Console.WriteLine(" Value: {0}", m1.value); 

    // Ask queue name and store it 
    System.Console.WriteLine("Enter a queue name to publish the message to: "); 
    string QueueName = (System.Console.ReadLine()).ToString(); 
    obj1.publish(QueueName); 

    System.Console.WriteLine("Enter another queue name: "); 
    QueueName = (System.Console.ReadLine()).ToString(); 
    obj1.publish(QueueName); 

    // Write message to the queue 
    obj1.write(m1); 

} 
} 

//MB2.cs

using System; 
using System.IO; 
using System.Collections.Generic; 
using System.Runtime.Serialization; 
using System.Runtime.Serialization.Formatters.Binary; 
using RabbitMQ.Client; 
using RabbitMQ.Client.Events; 
using UtilityMeasurement; 

public interface IMessageBus 
{  
string MsgSys  // Property 1 
{ 
    get; 
    set; 
} 

void write (Measurement m1); 
Measurement read(); 
void publish(string queue); 
void subscribe(string queue); 
} 

public class Rabbit : IMessageBus 
{ 
// Implementation of methods for Rabbit class go here 
private List<string> publishQ = new List<string>(); 
private List<string> subscribeQ = new List<string>(); 


public void write (Measurement m1) 
{ 
    byte[] body = Measurement.AltSerialize(m1); 

    IConnection connection = factory.CreateConnection(); 
    IModel channel = connection.CreateModel(); 

    foreach (string queue in publishQ) 
    { 
     channel.BasicPublish("", queue, null, body); 
     Console.WriteLine("\n [x] Sent to queue {0}.", queue); 
    } 
} 

public void publish(string queueName) 
{  
    channel.QueueDeclare(queueName, true, false, false, null); //durable=true 
    publishQ.Add(queueName); //and, add it the list of queue names to publish to 
} 

public Measurement read() 
{ 
    QueueingBasicConsumer consumer = new QueueingBasicConsumer(channel); 
    foreach (string queue in subscribeQ) 
    { 
     channel.BasicConsume(queue, true, consumer); 
    } 
    System.Console.WriteLine(" [*] Waiting for messages." + 
          "To exit press CTRL+C"); 
    BasicDeliverEventArgs ea = 
     (BasicDeliverEventArgs)consumer.Queue.Dequeue(); 
    return Measurement.AltDeSerialize(ea.Body); 
} 

public void subscribe(string queueName) 
{ 
    channel.QueueDeclare(queueName, true, false, false, null); 
    subscribeQ.Add(queueName); 
} 

public static string MsgSysName; 
public string MsgSys 
{ 
    get 
    { 
     return MsgSysName; 
    } 
    set 
    { 
     MsgSysName = value; 
    } 
} 

public Rabbit(string _msgSys) //Constructor 
{ 
    ConnectionFactory factory = new ConnectionFactory(); 
    factory.HostName = "localhost"; 

    System.Console.WriteLine("\nMsgSys: RabbitMQ"); 
    MsgSys = _msgSys; 
} 
} 


public class Zmq : IMessageBus 
{ 
public void write (Measurement m1) 
{ 
    // 
} 
public Measurement read() 
{ 
    // 
    return null; 
} 
public void publish(string queue) 
{ 
// 
} 
public void subscribe(string queue) 
{ 
//  
} 

public static string MsgSysName; 
public string MsgSys 
{ 
    get 
    { 
     return MsgSysName; 
    } 
    set 
    { 
     MsgSysName = value; 
    } 
} 

// Implementation of methods for Zmq class go here 
public Zmq(string _msgSys) //Constructor 
{ 
    System.Console.WriteLine("ZMQ"); 
    MsgSys = _msgSys; 
} 
} 

public class MessageBusFactory 
{ 
public static IMessageBus GetMessageBus(string MsgSysName) 
{ 
    switch (MsgSysName) 
    { 
     case "Zmq": 
      return new Zmq(MsgSysName); 
     case "Rabbit": 
      return new Rabbit(MsgSysName); 
     default: 
      throw new ArgumentException("Messaging type " + 
       MsgSysName + " not supported."); 
    } 
} 
} 

public class MainClass 
{ 
    public static void Main() 
    { 
    //Asks for the message system 
    System.Console.WriteLine("\nEnter name of messageing system: "); 
    System.Console.WriteLine("Usage: [Rabbit] [Zmq]"); 
    string MsgSysName = (System.Console.ReadLine()).ToString(); 

    //Declare an IMessageBus instance: 
    //Here, an object of the corresponding Message System 
     // (ex. Rabbit, Zmq, etc) is instantiated 
    IMessageBus obj1 = MessageBusFactory.GetMessageBus(MsgSysName); 

    System.Console.WriteLine("\nA {0} object is now created.", MsgSysName); 

    System.Console.WriteLine("Enter a queue to subscribe to: "); 
    string QueueName = (System.Console.ReadLine()).ToString(); 
    obj1.subscribe(QueueName); 

    //Create a new Measurement object m2 
    Measurement m2 = new Measurement(); 

    //Read message into m2 
    m2 = obj1.read(); 
    m2.id = 11; 
    System.Console.WriteLine("\nMessage received from queue {0}:\n ID: {1}",QueueName, m2.id); 
    System.Console.WriteLine(" Time: {0}", m2.time); 
    System.Console.WriteLine(" Value: {0}", m2.value); 
} 
} 

Répondre

2

Je viens de créer une vanille VS2010 C# projet d'application Console avec Refer.cs et App1.cs dans le même projet.

J'ai fait les modifications suivantes:

  • Ajouté RabbitMQ.Client.dll
  • Suppression des attributs AssemblyVersion
  • chaîne Ajouté [] args la méthode principale de App1.cs

En outre, j'ai changé:

factory.HostName = "localhost"; 

à ceci:

factory.HostName = "192.168.56.101"; 

Quelle est l'adresse IP à mon Ubuntu VirtualBox VM en cours d'exécution rabbitmq-serveur. Aucune exception n'a été levée et le message a bien été reçu sur le serveur.

Tous les signes indiquent la configuration du serveur avec ce qui est indiqué. Je suppose que votre serveur rabbitmq ne fonctionne pas du tout, qu'il ne fonctionne pas sur localhost ou qu'il y a un problème de connectivité avec le port 5672.

+0

@KG J'ai supprimé les attributs AssemblyVersion et cela a fonctionné. J'ajoute la DLL RabbitMQ.Client quand je compile à la fois app1.cs et app2.cs (je travaille sur la ligne de commande). Donc, merci beaucoup! Mais, je ne vois pas pourquoi cela pourrait être un problème? – Demi

+0

@Demi le projet AssemblyInfo possède déjà un attribut AssemblyVersion. Vous ne devriez même pas pouvoir compiler cela s'il existe à deux endroits. Si votre projet --n'a pas - AssemblyInfo.cs, vous n'auriez pas de conflit. Utilisez-vous Visual Studio? – karlgrz

+0

@KG Fera. Sur une note similaire, j'ai encapsulé les codes d'envoi et de réception dans une classe, créé un constructeur et mis la déclaration pour usine, connexion, canal dans ce constructeur en espérant que l'objet qui sera créé sur app1 et app2 chacun pour travailler dessus connexion. Cependant, lorsque j'essaie d'utiliser factory, connection et channel dans les méthodes subscribe et publish, j'ai une erreur disant qu'il ne connaît pas ces attributs. Comment pouvez-vous rendre la connexion, le nom d'hôte etc public à la classe afin que les méthodes de la classe exploitent cette déclaration? – Demi