示例#1
0
int main (void)
{
    //  Prepare our context and sockets
    zctx_t *ctx = zctx_new ();
    void *publisher = zsocket_new (ctx, ZMQ_PUB);
    zsocket_bind (publisher, "tcp://*:5557");

    int64_t sequence = 0;
    srandom ((unsigned) time (NULL));

    //  Start state manager and wait for synchronization signal
    void *updates = zthread_fork (ctx, state_manager, NULL);
    free (zstr_recv (updates));

    while (!zctx_interrupted) {
        //  Distribute as key-value message
        kvmsg_t *kvmsg = kvmsg_new (++sequence);
        kvmsg_fmt_key  (kvmsg, "%d", randof (10000));
        kvmsg_fmt_body (kvmsg, "%d", randof (1000000));
        kvmsg_send     (kvmsg, publisher);
        kvmsg_send     (kvmsg, updates);
        kvmsg_destroy (&kvmsg);
    }
    printf (" Interrupted\n%d messages out\n", (int) sequence);
    zctx_destroy (&ctx);
    return 0;
}
示例#2
0
static int
s_snapshots (zloop_t *loop, zmq_pollitem_t *poller, void *args)
{
    clonesrv_t *self = (clonesrv_t *) args;

    zframe_t *identity = zframe_recv (poller->socket);
    if (identity) {
        //  Request is in second frame of message
        char *request = zstr_recv (poller->socket);
        char *subtree = NULL;
        if (streq (request, "ICANHAZ?")) {
            free (request);
            subtree = zstr_recv (poller->socket);
        }
        else
            printf ("E: bad request, aborting\n");

        if (subtree) {
            //  Send state socket to client
            kvroute_t routing = { poller->socket, identity, subtree };
            zhash_foreach (self->kvmap, s_send_single, &routing);

            //  Now send END message with sequence number
            zclock_log ("I: sending shapshot=%d", (int) self->sequence);
            zframe_send (&identity, poller->socket, ZFRAME_MORE);
            kvmsg_t *kvmsg = kvmsg_new (self->sequence);
            kvmsg_set_key  (kvmsg, "KTHXBAI");
            kvmsg_set_body (kvmsg, (byte *) subtree, 0);
            kvmsg_send     (kvmsg, poller->socket);
            kvmsg_destroy (&kvmsg);
            free (subtree);
        }
    }
    return 0;
}
示例#3
0
文件: clonesrv1.c 项目: brikou/zguide
int main (void)
{
    //  Prepare our context and publisher socket
    zctx_t *ctx = zctx_new ();
    void *publisher = zsocket_new (ctx, ZMQ_PUB);
    zsocket_set_hwm (publisher, 0);
    zsocket_bind (publisher, "tcp://*:5556");
    zclock_sleep (200);

    zhash_t *kvmap = zhash_new ();
    int64_t sequence = 0;
    srandom ((unsigned) time (NULL));

    while (!zctx_interrupted) {
        //  Distribute as key-value message
        kvmsg_t *kvmsg = kvmsg_new (++sequence);
        kvmsg_fmt_key  (kvmsg, "%d", randof (10000));
        kvmsg_fmt_body (kvmsg, "%d", randof (1000000));
        kvmsg_send     (kvmsg, publisher);
        kvmsg_store   (&kvmsg, kvmap);
    }
    printf (" Interrupted\n%d messages out\n", (int) sequence);
    zhash_destroy (&kvmap);
    zctx_destroy (&ctx);
    return 0;
}
示例#4
0
static void
state_manager (void *args, zctx_t *ctx, void *pipe)
{
    zhash_t *kvmap = zhash_new ();

    zstr_send (pipe, "READY");
    void *snapshot = zsocket_new (ctx, ZMQ_ROUTER);
    zsocket_bind (snapshot, "tcp://*:5556");

    zmq_pollitem_t items [] = {
        { pipe, 0, ZMQ_POLLIN, 0 },
        { snapshot, 0, ZMQ_POLLIN, 0 }
    };
    int64_t sequence = 0;       //  Current snapshot version number
    while (!zctx_interrupted) {
        int rc = zmq_poll (items, 2, -1);
        if (rc == -1 && errno == ETERM)
            break;              //  Context has been shut down

        //  Apply state update from main thread
        if (items [0].revents & ZMQ_POLLIN) {
            kvmsg_t *kvmsg = kvmsg_recv (pipe);
            if (!kvmsg)
                break;          //  Interrupted
            sequence = kvmsg_sequence (kvmsg);
            kvmsg_store (&kvmsg, kvmap);
        }
        //  Execute state snapshot request
        if (items [1].revents & ZMQ_POLLIN) {
            zframe_t *identity = zframe_recv (snapshot);
            if (!identity)
                break;          //  Interrupted

            //  Request is in second frame of message
            char *request = zstr_recv (snapshot);
            if (streq (request, "ICANHAZ?"))
                free (request);
            else {
                printf ("E: bad request, aborting\n");
                break;
            }
            //  Send state snapshot to client
            kvroute_t routing = { snapshot, identity };

            //  For each entry in kvmap, send kvmsg to client
            zhash_foreach (kvmap, s_send_single, &routing);

            //  Now send END message with sequence number
            printf ("Sending state shapshot=%d\n", (int) sequence);
            zframe_send (&identity, snapshot, ZFRAME_MORE);
            kvmsg_t *kvmsg = kvmsg_new (sequence);
            kvmsg_set_key  (kvmsg, "KTHXBAI");
            kvmsg_set_body (kvmsg, (byte *) "", 0);
            kvmsg_send     (kvmsg, snapshot);
            kvmsg_destroy (&kvmsg);
        }
    }
    zhash_destroy (&kvmap);
}
示例#5
0
static void
collabclient_sendRedo_sfdfragment( cloneclient_t* cc,
				   SplineFont* sf,
				   SplineChar *sc, /* optional */
				   char* sfdfrag,  /* SFD that makes sense for redo */
				   char* msgtype,  /* will be MSG_TYPE_UNDO if set to zero */
				   int isLocalUndo )
{
    printf("collabclient_sendRedo_sfdfragment(top)\n");
    if( !cc )
	return;
    if( !msgtype )
	msgtype = MSG_TYPE_UNDO;
    
    char pos[100];
    char* uuid = sf->xuid;
    printf("uuid:%s\n", uuid );

    int idx = 0;
    char* sfd = sfdfrag;
    printf("read undo sfd, data:%p\n", sfd );
    if( DEBUG_SHOW_SFD_CHUNKS )
	printf("SENDING: %s\n\n", sfd );

    printf("timers1...\n" );
    cc->roundTripTimerWaitingSeq = cc->publisher_sendseq;
    BackgroundTimer_touch( cc->roundTripTimer );
    printf("timers2...\n" );
    printf("sfd:%p...\n", sfd );

    kvmsg_t *kvmsg = kvmsg_new(0);
    kvmsg_fmt_key  (kvmsg, "%s%d", SUBTREE, cc->publisher_sendseq++);
    kvmsg_set_body (kvmsg, sfd, strlen(sfd) );
    kvmsg_set_prop (kvmsg, "type", msgtype );
    kvmsg_set_prop (kvmsg, "uuid", uuid );
    if( sc )
    {
	sprintf(pos, "%d", sc->orig_pos );
	printf("pos:%s\n", pos );
	printf("sc.name:%s\n", sc->name );
    }
    
    size_t data_size = kvmsg_size (kvmsg);
    printf("data.size:%ld\n", data_size );

    kvmsg_set_prop (kvmsg, "pos", pos );
    if( sc )
	kvmsg_set_prop (kvmsg, "name", sc->name );
    sprintf(pos, "%d", isLocalUndo );
    kvmsg_set_prop (kvmsg, "isLocalUndo", pos );
    kvmsg_send     (kvmsg, cc->publisher);
    kvmsg_destroy  (&kvmsg);
    DEBUG("Sent a undo chunk of %zu bytes to the server\n",strlen(sfd));
    free(sfd);
}
示例#6
0
static void
collabclient_sendRedo_Internal( FontViewBase *fv, SplineChar *sc, Undoes *undo, int isLocalUndo )
{
    printf("collabclient_sendRedo_Internal()\n");
    cloneclient_t* cc = fv->collabClient;
    if( !cc )
	return;
    char* uuid = fv->sf->xuid;
    printf("uuid:%s\n", uuid );

    printf("________________________ WRITE undo.layer: %d layer_sz:%d\n",
	   undo->layer, sc->layer_cnt );
    
    int idx = 0;
    char filename[PATH_MAX];
    snprintf(filename, PATH_MAX, "%s/fontforge-collab-x.sfd", getTempDir() );
    FILE* f = fopen( filename, "wb" );
    SFDDumpUndo( f, sc, undo, "Undo", idx );
    fclose(f);
    printf("wrote undo sfd... filename: %s\n", filename );
    char* sfd = GFileReadAll( filename );
    printf("read undo sfd, data:%p\n", sfd );
    if( DEBUG_SHOW_SFD_CHUNKS )
	printf("SENDING: %s\n\n", sfd );

    printf("timers1...\n" );
    cc->roundTripTimerWaitingSeq = cc->publisher_sendseq;
    BackgroundTimer_touch( cc->roundTripTimer );
    printf("timers2...\n" );
    printf("sfd:%p...\n", sfd );

    kvmsg_t *kvmsg = kvmsg_new(0);
    kvmsg_fmt_key  (kvmsg, "%s%d", SUBTREE, cc->publisher_sendseq++);
    kvmsg_set_body (kvmsg, sfd, strlen(sfd) );
    kvmsg_set_prop (kvmsg, "type", MSG_TYPE_UNDO );
    kvmsg_set_prop (kvmsg, "uuid", uuid );
    char pos[100];
    sprintf(pos, "%d", sc->orig_pos );
    printf("pos:%s\n", pos );
    printf("sc.name:%s\n", sc->name );
    
    size_t data_size = kvmsg_size (kvmsg);
    printf("data.size:%ld\n", data_size );

    kvmsg_set_prop (kvmsg, "pos", pos );
    kvmsg_set_prop (kvmsg, "name", sc->name );
    sprintf(pos, "%d", isLocalUndo );
    kvmsg_set_prop (kvmsg, "isLocalUndo", pos );
    kvmsg_send     (kvmsg, cc->publisher);
    kvmsg_destroy (&kvmsg);
    DEBUG("Sent a undo chunk of %d bytes to the server\n",strlen(sfd));
    free(sfd);
}
示例#7
0
static int
s_send_hugz (zloop_t *loop, int timer_id, void *args)
{
    clonesrv_t *self = (clonesrv_t *) args;

    kvmsg_t *kvmsg = kvmsg_new (self->sequence);
    kvmsg_set_key  (kvmsg, "HUGZ");
    kvmsg_set_body (kvmsg, (byte *) "", 0);
    kvmsg_send     (kvmsg, self->publisher);
    kvmsg_destroy (&kvmsg);

    return 0;
}
示例#8
0
static void collabclient_sendSFD( void* ccvp, char* sfd, char* fontname )
{
    cloneclient_t* cc = (cloneclient_t*)ccvp;

    kvmsg_t *kvmsg = kvmsg_new(0);
    kvmsg_fmt_key  (kvmsg, "%s%d", SUBTREE, cc->publisher_sendseq++);
    kvmsg_set_body (kvmsg, sfd, strlen(sfd));
    kvmsg_set_prop (kvmsg, "type", MSG_TYPE_SFD );
    kvmsg_set_prop (kvmsg, "fontname", fontname );
//    kvmsg_set_prop (kvmsg, "ttl", "%d", randof (30));
    kvmsg_send     (kvmsg, cc->publisher);
    kvmsg_destroy (&kvmsg);
    DEBUG("Sent a SFD of %d bytes to the server\n",strlen(sfd));
    free(sfd);
}
示例#9
0
int main (void)
{
    //  Prepare our context and subscriber
    zctx_t *ctx = zctx_new ();
    void *snapshot = zsocket_new (ctx, ZMQ_DEALER);
    zsocket_connect (snapshot, "tcp://localhost:5556");
    void *subscriber = zsocket_new (ctx, ZMQ_SUB);
    zsockopt_set_subscribe (subscriber, "");
    zsocket_connect (subscriber, "tcp://localhost:5557");
    void *publisher = zsocket_new (ctx, ZMQ_PUSH);
    zsocket_connect (publisher, "tcp://localhost:5558");

    zhash_t *kvmap = zhash_new ();
    srandom ((unsigned) time (NULL));

    //  Get state snapshot
    int64_t sequence = 0;
    zstr_send (snapshot, "ICANHAZ?");
    while (TRUE) {
        kvmsg_t *kvmsg = kvmsg_recv (snapshot);
        if (!kvmsg)
            break;          //  Interrupted
        if (streq (kvmsg_key (kvmsg), "KTHXBAI")) {
            sequence = kvmsg_sequence (kvmsg);
            printf ("I: received snapshot=%d\n", (int) sequence);
            kvmsg_destroy (&kvmsg);
            break;          //  Done
        }
        kvmsg_store (&kvmsg, kvmap);
    }
    int64_t alarm = zclock_time () + 1000;
    while (!zctx_interrupted) {
        zmq_pollitem_t items [] = { { subscriber, 0, ZMQ_POLLIN, 0 } };
        int tickless = (int) ((alarm - zclock_time ()));
        if (tickless < 0)
            tickless = 0;
        int rc = zmq_poll (items, 1, tickless * ZMQ_POLL_MSEC);
        if (rc == -1)
            break;              //  Context has been shut down

        if (items [0].revents & ZMQ_POLLIN) {
            kvmsg_t *kvmsg = kvmsg_recv (subscriber);
            if (!kvmsg)
                break;          //  Interrupted

            //  Discard out-of-sequence kvmsgs, incl. heartbeats
            if (kvmsg_sequence (kvmsg) > sequence) {
                sequence = kvmsg_sequence (kvmsg);
                kvmsg_store (&kvmsg, kvmap);
                printf ("I: received update=%d\n", (int) sequence);
            }
            else
                kvmsg_destroy (&kvmsg);
        }
        //  If we timed-out, generate a random kvmsg
        if (zclock_time () >= alarm) {
            kvmsg_t *kvmsg = kvmsg_new (0);
            kvmsg_fmt_key  (kvmsg, "%d", randof (10000));
            kvmsg_fmt_body (kvmsg, "%d", randof (1000000));
            kvmsg_send     (kvmsg, publisher);
            kvmsg_destroy (&kvmsg);
            alarm = zclock_time () + 1000;
        }
    }
    printf (" Interrupted\n%d messages in\n", (int) sequence);
    zhash_destroy (&kvmap);
    zctx_destroy (&ctx);
    return 0;
}
示例#10
0
int main (void) 
{
    //  Prepare our context and subscriber
    void *context = zmq_init (1);
    void *subscriber = zmq_socket (context, ZMQ_SUB);
    zmq_setsockopt (subscriber, ZMQ_SUBSCRIBE, "", 0);
    zmq_connect (subscriber, "tcp://localhost:5556");

    void *snapshot = zmq_socket (context, ZMQ_XREQ);
    zmq_connect (snapshot, "tcp://localhost:5557");

    void *updates = zmq_socket (context, ZMQ_PUSH);
    zmq_connect (updates, "tcp://localhost:5558");

    s_catch_signals ();
    zhash_t *kvmap = zhash_new ();
    srandom ((unsigned) time (NULL));
    
    //  Get state snapshot
    int64_t sequence = 0;
    s_send (snapshot, "I can haz state?");
    while (!s_interrupted) {
        kvmsg_t *kvmsg = kvmsg_recv (snapshot);
        if (!kvmsg)
            break;          //  Interrupted
        if (streq (kvmsg_key (kvmsg), "KTHXBAI")) {
            sequence = kvmsg_sequence (kvmsg);
            kvmsg_destroy (&kvmsg);
            break;          //  Done
        }
        kvmsg_store (&kvmsg, kvmap);
    }
    printf ("I: received snapshot=%" PRId64 "\n", sequence);
    int zero = 0;
    zmq_setsockopt (snapshot, ZMQ_LINGER, &zero, sizeof (zero));
    zmq_close (snapshot);

    int64_t alarm = s_clock () + 1000;
    while (!s_interrupted) {
        zmq_pollitem_t items [] = { { subscriber, 0, ZMQ_POLLIN, 0 } };
        int tickless = (int) ((alarm - s_clock ()));
        if (tickless < 0)
            tickless = 0;
        int rc = zmq_poll (items, 1, tickless * 1000);
        if (rc == -1)
            break;              //  Context has been shut down
        
        if (items [0].revents & ZMQ_POLLIN) {
            kvmsg_t *kvmsg = kvmsg_recv (subscriber);
            if (!kvmsg)
                break;          //  Interrupted

            //  Discard out-of-sequence kvmsgs, incl. heartbeats
            if (kvmsg_sequence (kvmsg) > sequence) {
                sequence = kvmsg_sequence (kvmsg);
                kvmsg_store (&kvmsg, kvmap);
                printf ("I: received update=%" PRId64 "\n", sequence);
            }
            else
                kvmsg_destroy (&kvmsg);
        }
        //  If we timed-out, generate a random kvmsg
        if (s_clock () >= alarm) {
            kvmsg_t *kvmsg = kvmsg_new (0);
            kvmsg_fmt_key  (kvmsg, "%d", randof (10000));
            kvmsg_fmt_body (kvmsg, "%d", randof (1000000));
            kvmsg_send (kvmsg, updates);
            kvmsg_destroy (&kvmsg);
            alarm = s_clock () + 1000;
        }
    }
    zhash_destroy (&kvmap);

    printf (" Interrupted\n%" PRId64 " messages in\n", sequence);
    zmq_setsockopt (updates, ZMQ_LINGER, &zero, sizeof (zero));
    zmq_close (updates);
    zmq_close (subscriber);
    zmq_term (context);
    return 0;
}
示例#11
0
int main (void)
{
    //  Prepare our context and sockets
    zctx_t *ctx = zctx_new ();
    void *snapshot = zsocket_new (ctx, ZMQ_ROUTER);
    zsocket_bind (snapshot, "tcp://*:5556");
    void *publisher = zsocket_new (ctx, ZMQ_PUB);
    zsocket_bind (publisher, "tcp://*:5557");
    void *collector = zsocket_new (ctx, ZMQ_PULL);
    zsocket_bind (collector, "tcp://*:5558");

    //  .split body of main task
    //  The body of the main task collects updates from clients and
    //  publishes them back out to clients:

    int64_t sequence = 0;
    zhash_t *kvmap = zhash_new ();

    zmq_pollitem_t items [] = {
        { collector, 0, ZMQ_POLLIN, 0 },
        { snapshot, 0, ZMQ_POLLIN, 0 }
    };
    while (!zctx_interrupted) {
        int rc = zmq_poll (items, 2, 1000 * ZMQ_POLL_MSEC);

        //  Apply state update sent from client
        if (items [0].revents & ZMQ_POLLIN) {
            kvmsg_t *kvmsg = kvmsg_recv (collector);
            if (!kvmsg)
                break;          //  Interrupted
            kvmsg_set_sequence (kvmsg, ++sequence);
            kvmsg_send (kvmsg, publisher);
            kvmsg_store (&kvmsg, kvmap);
            printf ("I: publishing update %5d\n", (int) sequence);
        }
        //  Execute state snapshot request
        if (items [1].revents & ZMQ_POLLIN) {
            zframe_t *identity = zframe_recv (snapshot);
            if (!identity)
                break;          //  Interrupted

            //  Request is in second frame of message
            char *request = zstr_recv (snapshot);
            if (streq (request, "ICANHAZ?"))
                free (request);
            else {
                printf ("E: bad request, aborting\n");
                break;
            }
            //  Send state snapshot to client
            kvroute_t routing = { snapshot, identity };

            //  For each entry in kvmap, send kvmsg to client
            zhash_foreach (kvmap, s_send_single, &routing);

            //  Now send END message with sequence number
            printf ("I: sending shapshot=%d\n", (int) sequence);
            zframe_send (&identity, snapshot, ZFRAME_MORE);
            kvmsg_t *kvmsg = kvmsg_new (sequence);
            kvmsg_set_key  (kvmsg, "KTHXBAI");
            kvmsg_set_body (kvmsg, (byte *) "", 0);
            kvmsg_send     (kvmsg, snapshot);
            kvmsg_destroy (&kvmsg);
        }
    }
    printf (" Interrupted\n%d messages handled\n", (int) sequence);
    zhash_destroy (&kvmap);
    zctx_destroy (&ctx);

    return 0;
}