2012-05-03 9 views
9

Sto lavorando a un progetto che coinvolge diversi programmi C++ che ciascuno prende input e genera output. I dati (da decine a centinaia di byte, probabilmente JSON) essenzialmente fluiscono (in modo asincrono) in una direzione, e i programmi dovranno trovarsi su diversi computer Linux attorno alla LAN.Consigli per code di messaggi remoti C/C++

Poiché i dati sono in un'unica direzione, non credo di aver bisogno di un modello transazionale come HTTP. Penso che un modello di coda dei messaggi (fire and forget) abbia più senso e dovrebbe semplificare la logica di ciascun programma. È probabilmente sufficiente notare che il messaggio è stato aggiunto correttamente alla coda remota.

Quello che sto cercando sono raccomandazioni su come implementare questa coda di messaggi in C o C++. Sembra che le code di messaggi POSIX e Boost siano limitate a un singolo host e che RabbitMQ abbia un debole supporto C/C++ e che il supporto MQ4CPP non sia supportato in modo adeguato per un ruolo business-critical. Mi sbaglio di questo? Che dire di Boost ASIO o ACE o scrivere il codice socket personalmente? Attendo i vostri suggerimenti.

+2

[ZeroMQ è piuttosto carino] (http://www.zeromq.org). – user7116

+0

Grandi risposte, tutti, ma mi piace molto la semplicità di ZeroMQ. Se @sixlettervariables dovesse renderlo una risposta, lo accetterei. –

risposta

8

In termini di supporto di messaggistica semplice, ZeroMQ is hard to beat. È disponibile in molti collegamenti linguistici e supporta qualsiasi cosa, da semplice invio e ricezione a pub/sub, fanout o persino a una pipeline di messaggistica. Il codice è anche facile da digerire e rende piuttosto facile passare da un pattern all'altro.

Guardando le loro Weather Update Server sample (in 20 alcune lingue dispari) mostra quanto facile può essere quello di creare di pubblicazione/sottoscrizione configurazioni:

zmq::context_t context (1); 
zmq::socket_t publisher (context, ZMQ_PUB); 
publisher.bind("tcp://*:5556"); 
publisher.bind("ipc://weather.ipc"); 

while(1) { 
    // Send message to all subscribers 
    zmq::message_t message(20); 
    snprintf ((char *) message.data(), 20 , 
     "%05d %d %d", zipcode, temperature, relhumidity); 
    publisher.send(message); 
} 

ho usato su alcuni mista C# e processi Python senza più problemi .

1

Sto utilizzando la serializzazione Boost e l'invio di socket per un'applicazione simile. È possibile trovare un esempio di serializzazione qui:

http://code.google.com/p/cloudobserver/wiki/TutoriaslBoostSerialization

E in questa pagina:

http://www.boost.org/doc/libs/1_38_0/doc/html/boost_asio/examples.html

sotto serializzazione troverete esempi su come rendere i server ei client. Crea un server su una particolare porta e puoi generare più client su più computer che possono comunicare con quella porta.

Lo svantaggio di utilizzare la serializzazione boost è che ha un grande overhead se si dispone di una semplice struttura di dati da serializzare, ma lo rende facile.

2

Personalmente, se capisco la domanda, penso che dovresti usare una connessione TCP di livello inferiore. Ha tutte le consegne garantite che desideri e ha un'API Berkley Sockets piuttosto buona. Ho scoperto che se si desidera implementare un protocollo molto semplice (ad esempio la lunghezza del messaggio NBO a quattro byte, n byte di dati), è possibile ottenere molto semplice, molto personalizzabile e molto semplice. Se vai con questo, anche tu (come detto) ottieni un ottimo supporto C (che significa supporto C++, anche se le cose non sono in classi e metodi). Il codice socket è anche molto semplice, e hanno un IO asincrono con i flag asincroni standard per le funzioni IO Linux/UNIX/POSIX (questo è uno degli altri vantaggi, se sai qualcosa sulla programmazione POSIX, in pratica conosci l'API socket) .

Una delle migliori risorse per l'apprendimento delle API presa sono:

  • di Beej Guida alla rete Programmazione: http://beej.us/guide/bgnet/, questo è molto buono se avete bisogno del modello di programmazione complessiva, oltre a specifiche
  • pagine man : Se hai solo bisogno di firme delle funzioni, valori di ritorno e argomenti, questi sono tutto ciò di cui hai bisogno. Trovo quelli di Linux da molto ben scritto ed utili (Proof: Guardate il mio console: man, man, man, man, man, make, man, ...

Inoltre, per rendere i dati trasmissibili in rete, se i dati sono JSON, non ci sono problemi. Poiché JSON è solo ASCII (o UTF-8), può essere inviato come grezzo sulla rete con solo un'intestazione di lunghezza. A meno che il tuo tentativo di inviare qualcosa di complicato in binario, questo dovrebbe essere perfetto (se hai bisogno di complicati in binario, guarda la serializzazione o preparati per un sacco di Segmentation Fault).


Inoltre, probabilmente, se si utilizza il percorso socket, si desidera utilizzare TCP. Anche se UDP ti darà l'aspetto unidirezionale, il fatto che renderlo affidabile sta mettendo la tua soluzione a casa contro il TCP top-of-the-line dato dal kernel Linux, TCP è un'opzione ovvia.

1

Un'altra raccomandazione è la struttura distribuita OpenCL. Il documento The OpenCL C++ Wrapper for API fornisce ulteriori informazioni sulla libreria. In particolare, la funzione API cl::CommandQueue potrebbe essere di interesse per la creazione di code sui dispositivi all'interno di una configurazione di rete.

2

RabbitMQ è solo un'implementazione di AMQP. Potresti voler esaminare Apache Qpid o altre varianti che potrebbero essere più amichevoli di C/C++. C'è un libamqp per C anche se non ho esperienza di prima mano con esso. Non so esattamente quali siano le tue esigenze, ma AMQP, correttamente implementato, è la forza industriale e dovrebbe essere di ordine di grandezza più veloce e più stabile di qualsiasi cosa tu possa costruire a mano in un breve lasso di tempo.

1

Un'altra soluzione di messaggistica è ICE (http://www.zeroc.com/). È multipiattaforma, multi-lingua. Usa più di un approccio RPC.

+0

Sebbene sia un ottimo prodotto, [ICE is GPLed] (http://www.zeroc.com/licensing.html). A meno che il tuo codice sia GPL o sia disposto a pagare per una licenza commerciale, eviterei di farlo. – Void

Problemi correlati