2011-02-23 10 views
6

Estoy usando ZeroMQ de .NET y me atasqué tratando de solucionar un problema extraño. Tengo un socket de tipo PUSH y uno de tipo PULL sobre TCP. Cuando el cliente se desconecta, el servidor aún puede enviar un mensaje (tenga en cuenta que no se pasan indicadores al método Socket.Send) que obtiene mucho antes de comenzar a bloquearse y esperar a que el cliente se vuelva a conectar y entregue los mensajes que intento para enviar después.ZeroMQ PUSH/PULL y mensaje perdido

¿Cómo puedo evitar perder el mensaje (o en el peor de los casos, probar si un cliente está conectado y si no envía un mensaje falso que puedo permitir perder)?

¡Gracias de antemano!

Edit: pruebas adicionales revelan que si espero 1 segundo después de enviar el primer mensaje después de la desconexión por el cliente, el segundo bloqueará, pero si no espero en absoluto puedo enviar tantos mensajes como Quiero y todos se perderán. Eso es bastante confuso ...

Respuesta

3

La documentación de ZeroMQ señala que este es un problema con las configuraciones PUSH/PULL y sugiere el siguiente patrón: una adición de una configuración REP/REQ para proporcionar coordinación de nodos cuando se espera un número fijo de suscriptores Sin embargo, si no puede saber la cantidad de suscriptores por adelantado, debe considerar cambiar su protocolo para que sea más flexible a estas condiciones.

Synchronized publisher in C (from ZGuide)

// 
//  Synchronized publisher 
// 
#include "zhelpers.h" 

//  We wait for 10 subscribers 
#define SUBSCRIBERS_EXPECTED  10 

int main (void)  
{ 
    s_version_assert (2, 1); 
    void *context = zmq_init (1); 

   //  Socket to talk to clients 
    void *publisher = zmq_socket (context, ZMQ_PUB); 
    zmq_bind (publisher, "tcp://*:5561"); 

    //  Socket to receive signals 
    void *syncservice = zmq_socket (context, ZMQ_REP); 
    zmq_bind (syncservice, "tcp://*:5562"); 

    //  Get synchronization from subscribers 
    int subscribers = 0; 
    while (subscribers < SUBSCRIBERS_EXPECTED) { 
        //  - wait for synchronization request 
        char *string = s_recv (syncservice); 
        free (string); 
        //  - send synchronization reply 
        s_send (syncservice, ""); 
        subscribers++; 
    } 
    //  Now broadcast exactly 1M updates followed by END 
    int update_nbr; 
    for (update_nbr = 0; update_nbr < 1000000; update_nbr++) 
        s_send (publisher, "Rhubarb"); 

    s_send (publisher, "END"); 

    zmq_close (publisher); 
    zmq_close (syncservice); 
    zmq_term (context); 
    return 0; 
}