2013-06-18 16 views
5

Sto cercando di riscrivere uno dei nostri vecchi server utilizzando ZeroMQ, per ora ho la seguente configurazione del server, (che lavora per le richieste Zmq):È possibile utilizzare ZeroMQ per accettare le richieste socket tradizionali?

using (var context = ZmqContext.Create()) 
    using (var server = context.CreateSocket(SocketType.REP)) { 
     server.Bind("tcp://x.x.x.x:5705"); 

     while (true) { ... } 

Questo tipo di configurazione funziona bene se io utilizzare la libreria client Zmq per collegare context.CreateSocket(SocketType.REQ)

Ma purtroppo abbiamo un sacco di codice legacy che ha bisogno di connettersi a questo server e le prese sono creati utilizzando librerie di socket .net:

Socket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); 
    Socket.Connect(ipAddress, port); 

c'è un modo di scrivere un server ZeroMQ per accettare queste connessioni socket .net tradizionali?

risposta

11

È possibile ottenere ciò utilizzando ZMQ_STREAM sockets.

Si noti che a partire da zeroMQ 4.x, l'opzione router RAW has been deprecated per un nuovo tipo di socket ZMQ_STREAM, che funziona allo stesso modo di ROUTER + RAW.

Sembra che sia destinato a evolversi, comunque.

Recentemente ho provato zoccoli ZMQ_STREAM nella versione 4.0.1.

È possibile aprirne uno, utilizzare zmq_rcv fino a quando non si riceve l'intero messaggio (è necessario controllare che sia completo) oppure zmq_msg_rcv per consentire a ZeroMQ di gestirlo. Riceverai una identificatore messaggio parte, proprio come l'identificatore si troverebbero in ROUTER prese, direttamente seguito da uno SOLOcorpo parte. Non esiste un delimitatore vuoto tra di loro come se si utilizzasse uno zoccolo REQ che comunica con una presa ROUTER. Quindi, se li instradi, assicurati di aggiungerlo tu stesso.

Attenzione però: se c'è latenza all'altra estremità o se il tuo messaggio supera i buffer ZeroMQ ZMQ_STREAM (il mio è lungo 8192 byte), il tuo messaggio può essere interpretato da zeroMQ come una serie di messaggi.

In tal caso, si riceverà il maggior numero di messaggi ZeroMQ diversi, tra cui sia l'identificatore parte e la parte del corpo, ed è il vostro lavoro per aggregare loro, sapendo che se diversi clienti stanno parlando alla presa STREAM potrebbero essere confusi. Personalmente uso una tabella hash usando l'identificatore binario come chiave ed elimini la voce dalla tabella quando so che il messaggio è completo e inviato al nodo successivo.

L'invio tramite ZMQ_STREAM con zmq_msg_send o zmq_send funziona correttamente.

3

Probabilmente è necessario utilizzare il tipo di socket RAW di zmq (anziché REP) per connettersi e leggere i dati del client senza framing specifico zmq.

HTTP Server in C (dal blog di Pieter)
http://hintjens.com/blog:42

RAW Socket Tipo di informazioni
https://github.com/hintjens/libzmq/commit/777c38ae32a5d1799b3275d38ff8d587c885dd55

+0

Ehi @Raffian, grazie, ma non sono sicuro di come implementarlo. Non c'è SocketType di RAW, hai un esempio che potresti fornire? –

+1

Sì, ecco un Pieter che ha scritto, http://hintjens.com/blog:42, è fondamentalmente un server HTTP che usa zmq raw socket, è in C, ma dovresti essere in grado di portarlo su .net, a patto che. net supporta 'socket RAW', so che la libreria Java zmq pura (jeromq) non ... spero che aiuti. – raffian

+0

Grazie a @Raffian, non riesco a collegarmi direttamente alla lib di ZMQ, sto usando clrzmq, l'implementazione .Net, quindi potrebbe non essere possibile –

Problemi correlati