int mdp_client_send (mdp_client_t **self_p, void *socket) { assert (socket); assert (self_p); assert (*self_p); mdp_client_t *self = *self_p; // If we're sending to a ROUTER, we send the address first zmsg_t *msg = zmsg_new (); if (zsocket_type (socket) == ZMQ_ROUTER) { assert (self->address); zmsg_add (msg, self->address); self->address = NULL; // Owned by msg now } // Send header fields zmsg_addstr (msg, ""); zmsg_addstr (msg, "MDPC01"); // All messages have the same structure zmsg_addstr (msg, self->service); zmsg_add (msg, self->body); self->body = NULL; // Send the message and destroy mdp_client object int rc = zmsg_send (&msg, socket); mdp_client_destroy (self_p); return rc; }
int main (int argc, char *argv[]) { if (argc != 3) { exit (-1); } int numb_msgs = atoi (argv[2]); zctx_t *ctx = zctx_new (); void *dealer = zsocket_new (ctx, ZMQ_DEALER); zsocket_set_linger (dealer, -1); zsocket_connect (dealer, "%s:9000", argv[1]); void *sub = zsocket_new (ctx, ZMQ_SUB); zsocket_connect (sub, "%s:9002", argv[1]); zmq_setsockopt (sub, ZMQ_SUBSCRIBE, "all", 4); int64_t time[2]; zmq_pollitem_t pollitem[1] = { {sub, 0, ZMQ_POLLIN} }; zmq_poll (pollitem, 1, -1); zmsg_t *signal = zmsg_recv (sub); zmsg_destroy (&signal); char blob[SIZE] = { 0 }; zmsg_t *msg = zmsg_new (); zframe_t *frame = zframe_new (blob, SIZE); zmsg_add (msg, frame); time[0] = zclock_time (); int i; for (i = 0; i < numb_msgs; i++) { zmsg_t *nmsg = zmsg_dup (msg); zmsg_send (&nmsg, dealer); } time[1] = zclock_time (); zmsg_destroy (&msg); zmq_poll (pollitem, 1, -1); msg = zmsg_recv (sub); zmsg_destroy (&msg); msg = zmsg_new (); frame = zframe_new (time, sizeof (int64_t) * 2); zmsg_add (msg, frame); zmsg_send (&msg, dealer); zctx_destroy (&ctx); }
int main (int argc, char *argv []) { int verbose = (argc > 1 && streq (argv [1], "-v")); mdcli_t *session = mdcli_new ("tcp://localhost:5555", verbose); // 1. Send 'echo' request to Titanic zmsg_t *request = zmsg_new (); zmsg_addstr (request, "echo"); zmsg_addstr (request, "Hello world"); zmsg_t *reply = s_service_call ( session, "titanic.request", &request); zframe_t *uuid = NULL; if (reply) { uuid = zmsg_pop (reply); zmsg_destroy (&reply); zframe_print (uuid, "I: request UUID "); } // 2. Wait until we get a reply while (!zctx_interrupted) { zclock_sleep (100); request = zmsg_new (); zmsg_add (request, zframe_dup (uuid)); zmsg_t *reply = s_service_call ( session, "titanic.reply", &request); if (reply) { char *reply_string = zframe_strdup (zmsg_last (reply)); printf ("Reply: %s\n", reply_string); free (reply_string); zmsg_destroy (&reply); // 3. Close request request = zmsg_new (); zmsg_add (request, zframe_dup (uuid)); reply = s_service_call (session, "titanic.close", &request); zmsg_destroy (&reply); break; } else { printf ("I: no reply yet, trying again...\n"); zclock_sleep (5000); // Try again in 5 seconds } } zframe_destroy (&uuid); mdcli_destroy (&session); return 0; }
static void s_check_directory (s_agent_t *self) { // Get latest snapshot and build a patches list for any changes // All patches are built using a virtual path starting at "/" zdir_t *dir = zdir_new (self->path, NULL); zlist_t *patches = zdir_diff (self->dir, dir, "/"); // Drop old directory and replace with latest version zdir_destroy (&self->dir); self->dir = dir; while (zlist_size (patches)) { zdir_patch_t *patch = (zdir_patch_t *) zlist_pop (patches); if (zdir_patch_op (patch) == patch_create) { // Shout new files to DROPS group // Stupidest possible approach: send whole file as one frame // Truncate file at arbitrary limit of 10MB zfile_t *file = zdir_patch_file (patch); if (zfile_input (file) == 0) { zchunk_t *chunk = zfile_read (file, 10 * 1024 * 1024, 0); assert (chunk); zmsg_t *msg = zmsg_new (); zmsg_addstr (msg, "CREATE"); zmsg_addstr (msg, zdir_patch_vpath (patch)); zmsg_add (msg, zframe_new (zchunk_data (chunk), zchunk_size (chunk))); zchunk_destroy (&chunk); zyre_shout (self->zyre, "DROPS", &msg); } } zdir_patch_destroy (&patch); } zlist_destroy (&patches); }
int mdp_worker_send (mdp_worker_t **self_p, void *socket) { assert (socket); assert (self_p); assert (*self_p); mdp_worker_t *self = *self_p; // If we're sending to a ROUTER, we send the address first zmsg_t *msg = zmsg_new (); if (zsockopt_type (socket) == ZMQ_ROUTER) { assert (self->address); zmsg_add (msg, self->address); self->address = NULL; // Owned by msg now } // Send header fields zmsg_addstr (msg, ""); zmsg_addstr (msg, "MDPW01"); zmsg_addmem (msg, &self->id, 1); switch (self->id) { case MDP_WORKER_READY: zmsg_addstr (msg, self->service); break; case MDP_WORKER_REQUEST: zmsg_add (msg, self->client); self->client = NULL; zmsg_add (msg, self->body); self->body = NULL; break; case MDP_WORKER_REPLY: zmsg_add (msg, self->client); self->client = NULL; zmsg_add (msg, self->body); self->body = NULL; break; case MDP_WORKER_HEARBEAT: break; case MDP_WORKER_DISCONNECT: break; } // Send the message and destroy mdp_worker object int rc = zmsg_send (&msg, socket); mdp_worker_destroy (self_p); return rc; }
static void client_execute (client_t *self, int event) { self->next_event = event; while (self->next_event) { self->event = self->next_event; self->next_event = 0; printf ("State=%s, event=%s\n", s_state_name [self->state], s_event_name [self->event]); switch (self->state) { case start_state: if (self->event == ohai_event) { check_credentials_action (self); self->state = authenticated_state; } break; case authenticated_state: if (self->event == ok_event) { zmsg_addstr (self->reply, "OHAI-OK"); self->state = ready_state; } else if (self->event == error_event) { zmsg_addstr (self->reply, "WTF"); self->state = start_state; } break; case ready_state: if (self->event == icanhaz_event) { zmsg_addstr (self->reply, "CHEEZBURGER"); } else if (self->event == hugz_event) { zmsg_addstr (self->reply, "HUGZ-OK"); } else if (self->event == heartbeat_event) { zmsg_addstr (self->reply, "HUGZ"); } break; case stopped_state: // Discard all events silently break; } if (zmsg_size (self->reply) > 1) { puts ("Send message to client"); zmsg_dump (self->reply); zmsg_send (&self->reply, self->router); self->reply = zmsg_new (); zmsg_add (self->reply, zframe_dup (self->address)); } } }
void adminCmdTest(Worker *self, Session *session, char *args, zmsg_t *replyMsg) { info("Test command launched."); size_t memSize; void *memory = dumpToMem( "[03:12:32][main.c:30 in writePacketToFile] E9 0C 73 2A 86 02 35 00 A2 4E 00 00 02 01 05 00 | ..s*..5..N......\n" "[03:12:32][main.c:30 in writePacketToFile] 4E 61 6D 65 00 0C 00 44 61 72 6B 48 6F 72 69 7A | Name...DarkHoriz\n" "[03:12:32][main.c:30 in writePacketToFile] 6F 6E 00 04 00 57 68 6F 00 0A 00 4C 6F 74 68 62 | on...Who...Lothb\n" "[03:12:32][main.c:30 in writePacketToFile] 72 6F 6F 6B 00 | rook." , NULL, &memSize ); zmsg_add(replyMsg, zframe_new(memory, memSize)); }
void zeromq_send_data(void *socket, char *identity, uint8_t *data, int size) { assert(socket); assert(data); zmsg_t *msg = zmsg_new(); zmsg_addstr (msg, "%s", identity); zframe_t *frame = zframe_new (data, size); zmsg_add (msg, frame); zmsg_send (&msg, socket); }
static client_t * client_new (void *router, char *hashkey, zframe_t *address) { client_t *self = (client_t *) zmalloc (sizeof (client_t)); self->heartbeat = 1000; self->router = router; self->hashkey = hashkey; self->address = address; self->state = start_state; self->reply = zmsg_new (); zmsg_add (self->reply, zframe_dup (self->address)); return self; }
void rrtask_manager_fn(void *args, zctx_t *ctx, void *pipe) { rrwrk_t *self = (rrwrk_t *)args; zstr_send(pipe, "READY"); while (true) { zmq_pollitem_t item = {pipe, 0, ZMQ_POLLIN, 0}; int rc = zmq_poll(&item, 1, -1); if (rc == -1 && errno == ETERM) break; //** Context has been shut down zmsg_t *msg; if (item.revents & ZMQ_POLLIN) { //** Receives task input from pipe msg = zmsg_recv(pipe); zframe_t *data_in = zmsg_last(msg); rrtask_data_t *input = rrtask_data_new(); rrtask_set_data(input, zframe_data(data_in), zframe_size(data_in)); //** User callback function to perform the task rrtask_data_t *output = self->cb(input); zframe_t *data_out = zframe_new(output->data, output->len); //** Removes input data from message and destroy it zmsg_remove(msg, data_in); zframe_destroy(&data_in); //** Adds output data to the message and send it to pipe zmsg_add(msg, data_out); zmsg_send(&msg, pipe); //** Destroys task input and output data rrtask_data_destroy(&input); rrtask_data_destroy(&output); zmsg_destroy(&msg); } if (zctx_interrupted) { printf("I am destroying this message.\n"); zmsg_destroy(&msg); break; } } }
int main (int argc, char *argv []) { int verbose = (argc > 1 && streq (argv [1], "-v")); zctx_t *ctx = zctx_new (); // Prepare server socket with predictable identity char *bind_endpoint = "tcp://*:5555"; char *connect_endpoint = "tcp://localhost:5555"; void *server = zsocket_new (ctx, ZMQ_ROUTER); zmq_setsockopt (server, ZMQ_IDENTITY, connect_endpoint, strlen (connect_endpoint)); zsocket_bind (server, bind_endpoint); printf ("I: service is ready at %s\n", bind_endpoint); while (!zctx_interrupted) { zmsg_t *request = zmsg_recv (server); if (verbose && request) zmsg_dump (request); if (!request) break; // Interrupted // Frame 0: identity of client // Frame 1: PING, or client control frame // Frame 2: request body zframe_t *identity = zmsg_pop (request); zframe_t *control = zmsg_pop (request); zmsg_t *reply = zmsg_new (); if (zframe_streq (control, "PING")) zmsg_addstr (reply, "PONG"); else { zmsg_add (reply, control); zmsg_addstr (reply, "OK"); } zmsg_destroy (&request); zmsg_push (reply, identity); if (verbose && reply) zmsg_dump (reply); zmsg_send (&reply, server); } if (zctx_interrupted) printf ("W: interrupted\n"); zctx_destroy (&ctx); return 0; }
zmsg_t * zmsg_recv (void *socket) { assert (socket); zmsg_t *self = zmsg_new (); while (1) { zframe_t *frame = zframe_recv (socket); if (!frame) { zmsg_destroy (&self); break; // Interrupted or terminated } zmsg_add (self, frame); if (!zframe_more (frame)) break; // Last message frame } return self; }
int _tmain(int argc, _TCHAR* argv[]) { zclock_sleep(20000); char* broker_loc = "tcp://localhost:5555"; zctx_t* ctx = zctx_new(); void* scket = zsocket_new(ctx,ZMQ_REQ); zsocket_connect(scket,broker_loc); zmsg_t* msg = zmsg_new(); zmsg_addstr(msg,TWRK_CLI_VER); zmsg_addstr(msg,"Echo"); zmsg_addstr(msg,TMSG_TYPE_REQUEST); int64_t sleep = 10*1000; zclock_sleep(sleep); zmsg_add(msg,zframe_new(&sleep,sizeof(sleep))); zmsg_send(&msg,scket); zmsg_t* reply = zmsg_recv(scket); zmsg_dump(reply); return 0; }
zmsg_t * zmsg_load (zmsg_t *self, FILE *file) { assert (file); if (!self) self = zmsg_new (); while (TRUE) { size_t frame_size; size_t rc = fread (&frame_size, sizeof (frame_size), 1, file); if (rc == 1) { zframe_t *frame = zframe_new (NULL, frame_size); rc = fread (zframe_data (frame), frame_size, 1, file); if (frame_size > 0 && rc != 1) break; // Unable to read properly, quit zmsg_add (self, frame); } else break; // Unable to read properly, quit } return self; }
static void s_self_handle_udp (self_t *self) { assert (self); char peername [INET_ADDRSTRLEN]; zframe_t *frame = zsys_udp_recv (self->udpsock, peername); // If filter is set, check that beacon matches it bool is_valid = false; if (self->filter) { byte *filter_data = zframe_data (self->filter); size_t filter_size = zframe_size (self->filter); if ( zframe_size (frame) >= filter_size && memcmp (zframe_data (frame), filter_data, filter_size) == 0) is_valid = true; } // If valid, discard our own broadcasts, which UDP echoes to us if (is_valid && self->transmit) { byte *transmit_data = zframe_data (self->transmit); size_t transmit_size = zframe_size (self->transmit); if ( zframe_size (frame) == transmit_size && memcmp (zframe_data (frame), transmit_data, transmit_size) == 0) is_valid = false; } // If still a valid beacon, send on to the API if (is_valid) { zmsg_t *msg = zmsg_new (); assert (msg); zmsg_addstr (msg, peername); zmsg_add (msg, frame); zmsg_send (&msg, self->pipe); } else zframe_destroy (&frame); }
int main (int argc, char *argv[]) { if (argc != 4) { exit (-1); } int numb_msgs = atoi (argv[2]); int numb_unimp_threads = atoi (argv[3]); zctx_t *ctx = zctx_new (); void *router_imp = zsocket_new (ctx, ZMQ_ROUTER); zsocket_set_rcvhwm (router_imp, 500000000); zsocket_bind (router_imp, "%s:9000", argv[1]); void *router_unimp = zsocket_new (ctx, ZMQ_ROUTER); zsocket_set_rcvhwm (router_unimp, 500000000); zsocket_bind (router_unimp, "%s:9001", argv[1]); void *pub = zsocket_new (ctx, ZMQ_PUB); zsocket_bind (pub, "%s:9002", argv[1]); int64_t time[3]; int64_t idle=0; int64_t diff; zclock_sleep (1000); //send the signal to start zmsg_t *amsg = zmsg_new (); zmsg_add (amsg, zframe_new ("all", 4)); zmsg_send (&amsg, pub); zmq_pollitem_t pollitem[2] = { {router_imp, 0, ZMQ_POLLIN} , {router_unimp, 0, ZMQ_POLLIN} }; unsigned long av_dropped_priority=0; unsigned long dropped=0; unsigned long av_processed_priority=0; unsigned long processed=0; int i; int imp_counter = 0; int once = 1; int ndiffs = 0; unsigned char drop_priority = 0; for (i = 0; i < 2 * numb_msgs; i++) { diff = zclock_time (); if (zmq_poll (pollitem, 2, -1) == -1) { exit (-1); } diff = zclock_time () - diff; idle = idle + diff; update_drop_rate(&diff,&drop_priority,&ndiffs); if (pollitem[0].revents & ZMQ_POLLIN) { zmsg_t *msg = zmsg_recv (router_imp); if (!msg) { exit (-1); } zmsg_destroy (&msg); imp_counter++; if (imp_counter == numb_msgs) { time[0] = zclock_time (); } } else { if (pollitem[1].revents & ZMQ_POLLIN) { if (once) { time[1] = zclock_time (); once = 0; } zmsg_t *msg = zmsg_recv (router_unimp); if (!msg) { exit (-1); } zframe_t *frame = zmsg_unwrap (msg); zframe_destroy (&frame); unsigned char priority; memcpy (&priority, zframe_data (zmsg_first (msg)), 1); if (priority < drop_priority) { av_dropped_priority+=priority; dropped++; // printf ("dropped:%u\n", priority); zmsg_destroy (&msg); } else { av_processed_priority+=priority; processed++; // printf ("received:%u\n", priority); zmsg_destroy (&msg); } } } } time[2] = zclock_time (); printf ("msgs received:%d\n", i); amsg = zmsg_new (); zmsg_add (amsg, zframe_new ("all", 4)); zmsg_send (&amsg, pub); zmsg_t *msg = zmsg_recv (router_imp); zframe_t *frame = zmsg_unwrap (msg); zframe_destroy (&frame); int64_t time_imp[2]; frame = zmsg_pop (msg); memcpy (time_imp, zframe_data (frame), zframe_size (frame)); zframe_destroy (&frame); zmsg_destroy (&msg); int64_t time_unimp[numb_unimp_threads][2]; for(i=0; i<numb_unimp_threads; i++){ msg = zmsg_recv (router_unimp); frame = zmsg_unwrap (msg); zframe_destroy (&frame); frame = zmsg_pop (msg); memcpy (time_unimp[i], zframe_data (frame), zframe_size (frame)); zframe_destroy (&frame); zmsg_destroy (&msg); } //compute average latency printf ("\nTime when important msgs started to be sent: %lld\n", time_imp[0]); printf ("\nTime when important msgs were processed: %lld\n", time[0]); printf ("\nDifference: %lld\n", time[0] - time_imp[0]); for(i=0; i<numb_unimp_threads; i++){ printf ("\nTime when unimportant msgs started to be sent: %lld\n", time_unimp[i][0]); printf ("\nTime when unimportant msgs were processed: %lld\n", time[2]); printf ("\nDifference: %lld\n", time[2] - time_unimp[i][0]); } printf ("\nTime when unimportant msgs started to be processed: %lld\n", time[1]); printf ("idle time:%llu\n",idle); printf ("dropped msgs:%llu\n",dropped); printf ("av_dropped_priority:%llu\n",av_dropped_priority/dropped); printf ("processed msgs:%llu\n",processed); printf ("av_processed_priority:%llu\n",av_processed_priority/processed); }
void adminCmdSpawnPc(Worker *self, Session *session, char *args, zmsg_t *replyMsg) { // add a fake commander with a fake account CommanderInfo fakePc; commanderInfoInit(&fakePc); fakePc.pos = session->game.commanderSession.currentCommander.info.pos; fakePc.appearance.accountId = r1emuGenerateRandom64(&self->seed); fakePc.socialInfoId = r1emuGenerateRandom64(&self->seed); fakePc.pcId = r1emuGenerateRandom(&self->seed); fakePc.commanderId = r1emuGenerateRandom64(&self->seed); snprintf(fakePc.appearance.familyName, sizeof(fakePc.appearance.familyName), "PcID_%x", fakePc.pcId); snprintf(fakePc.appearance.commanderName, sizeof(fakePc.appearance.commanderName), "AccountID_%llx", fakePc.appearance.accountId); // register the fake socket session SocketSession fakeSocketSession; uint32_t sessionKey = r1emuGenerateRandom(&self->seed); uint8_t sessionKeyStr[SOCKET_SESSION_ID_SIZE]; socketSessionGenSessionKey((uint8_t *)&sessionKey, sessionKeyStr); sprintf(sessionKeyStr, "%.08x", sessionKey); socketSessionInit(&fakeSocketSession, fakePc.appearance.accountId, self->info.routerId, session->socket.mapId, sessionKeyStr, true); RedisSocketSessionKey socketKey = { .routerId = self->info.routerId, .sessionKey = sessionKeyStr }; redisUpdateSocketSession(self->redis, &socketKey, &fakeSocketSession); // register the fake game session GameSession fakeGameSession; gameSessionInit(&fakeGameSession, &fakePc); accountSessionInit(&fakeGameSession.accountSession, "DummyPC", sessionKeyStr, ACCOUNT_SESSION_PRIVILEGES_ADMIN); RedisGameSessionKey gameKey = { .routerId = fakeSocketSession.routerId, .mapId = fakeSocketSession.mapId, .accountId = fakeSocketSession.accountId }; redisUpdateGameSession(self->redis, &gameKey, sessionKeyStr, &fakeGameSession); info("Fake PC spawned.(SocketID=%s, SocialID=%I64x, AccID=%I64x, PcID=%x, CommID=%I64x)", sessionKeyStr, fakePc.socialInfoId, fakePc.appearance.accountId, fakePc.pcId, fakePc.commanderId); GameEventEnterPc event = { .updatePosEvent = { .mapId = fakeSocketSession.mapId, .info = fakePc } }; workerDispatchEvent(self, sessionKeyStr, EVENT_TYPE_ENTER_PC, &event, sizeof(event)); } void adminCmdAddItem(Worker *self, Session *session, char *args, zmsg_t *replyMsg) { uint32_t itemId = strtol(args, &args, 10); args++; uint32_t amount = strtol(args, &args, 10); uint32_t itemPosition = 1; ItemPkt item = { .uniqueId = r1emuGenerateRandom64(&self->seed), .amount = (!amount) ? 1 : amount, .inventoryIndex = INVENTORY_CAT_SIZE * INVENTORY_CAT_CONSUMABLE + itemPosition, .id = itemId }; zoneBuilderItemAdd(&item, INVENTORY_ADD_PICKUP, replyMsg); } void adminCmdJump(Worker *self, Session *session, char *args, zmsg_t *replyMsg) { if (strlen (args) == 0) { info("Jump without argument!"); // we must add a random with the map max x/y } else { char **arg; int argc; info("Jump with argument: %s", args); arg = strSplit(args, ' '); argc = 0; while (arg[++argc] != NULL); if (argc != 3) { info("Wrong number of argument, must be 3."); } else { PositionXYZ position; position.x = atof(arg[0]); info("x = %.6f", position.x); position.y = atof(arg[1]); info("y = %.6f", position.y); position.z = atof(arg[2]); info("z = %.6f", position.z); session->game.commanderSession.currentCommander.info.pos = position; zoneBuilderSetPos(session->game.commanderSession.currentCommander.info.pcId, &position, replyMsg); } free(arg); } } void adminCmdTest(Worker *self, Session *session, char *args, zmsg_t *replyMsg) { info("Test command launched."); size_t memSize; void *memory = dumpToMem( "[03:12:32][main.c:30 in writePacketToFile] E9 0C 73 2A 86 02 35 00 A2 4E 00 00 02 01 05 00 | ..s*..5..N......\n" "[03:12:32][main.c:30 in writePacketToFile] 4E 61 6D 65 00 0C 00 44 61 72 6B 48 6F 72 69 7A | Name...DarkHoriz\n" "[03:12:32][main.c:30 in writePacketToFile] 6F 6E 00 04 00 57 68 6F 00 0A 00 4C 6F 74 68 62 | on...Who...Lothb\n" "[03:12:32][main.c:30 in writePacketToFile] 72 6F 6F 6B 00 | rook." , NULL, &memSize ); zmsg_add(replyMsg, zframe_new(memory, memSize)); } void adminCmdWhere(Worker *self, Session *session, char *args, zmsg_t *replyMsg) { const uint16_t MAX_LEN = 128; char message[MAX_LEN]; PositionXYZ position; position = session->game.commanderSession.currentCommander.info.pos; snprintf(message, sizeof(message), "[%hu] x = %.0f, y = %.0f, z = %.0f", session->game.commanderSession.mapId, position.x, position.y, position.z); zoneBuilderChat(&session->game.commanderSession.currentCommander.info, message, replyMsg); } void adminCmdChangeCamera(Worker *self, Session *session, char *args, zmsg_t *replyMsg) { const uint16_t MAX_LEN = 128; char message[MAX_LEN]; PositionXYZ pos; float fspd; float ispd; info("Change Camera command used, args = %s", args); if (strlen (args) == 0) { pos.x = 0; pos.y = 0; pos.z = 0; zoneBuilderChangeCamera((uint8_t)0, &pos, (float)0, (float)0, replyMsg); } else { char **arg; int argc; arg = strSplit(args, ' '); argc = 0; while (arg[++argc] != NULL); if (argc >= 3) { pos.x = (strlen(arg[0]) == 1 && arg[0][0] == 'c') ? session->game.commanderSession.currentCommander.info.pos.x : atof(arg[0]); pos.y = (strlen(arg[1]) == 1 && arg[1][0] == 'c') ? session->game.commanderSession.currentCommander.info.pos.y : atof(arg[1]); pos.z = (strlen(arg[2]) == 1 && arg[2][0] == 'c') ? session->game.commanderSession.currentCommander.info.pos.z : atof(arg[2]); } if (argc == 3) zoneBuilderChangeCamera((uint8_t)1, &pos, (float)10, (float)0.7, replyMsg); else if (argc == 5) { fspd = atof(arg[3]); ispd = atof(arg[4]); zoneBuilderChangeCamera((uint8_t)1, &pos, fspd, ispd, replyMsg); } else { snprintf(message, sizeof(message), "Bad usage /changeCamera <x> <y> <z> {<fspd> <ispd>}"); zoneBuilderChat(&session->game.commanderSession.currentCommander.info, message, replyMsg); } free(arg); } } void adminCmdSetStamina(Worker *self, Session *session, char *args, zmsg_t *replyMsg) { if (strlen (args) == 0) { info("Set stamina needs a argument!"); } else { char **arg; int argc; info("Set stamina with argument: %s", args); arg = strSplit(args, ' '); argc = 0; while (arg[++argc] != NULL); if (argc != 1) { info("Wrong number of arguments, must be 1."); } else { uint32_t stamina = atoi(arg[0]) * 1000; info("Setting stamina to %d.", stamina); session->game.commanderSession.currentCommander.info.currentStamina = stamina; zoneBuilderStamina(stamina, replyMsg); } free(arg); } } void adminCmdSetSP(Worker *self, Session *session, char *args, zmsg_t *replyMsg) { if (strlen (args) == 0) { info("Set SP needs a argument!"); } else { char **arg; int argc; info("Set SP with argument: %s", args); arg = strSplit(args, ' '); argc = 0; while (arg[++argc] != NULL); if (argc != 1) { info("Wrong number of arguments, must be 1."); } else { uint32_t sp = atoi(arg[0]); info("Setting SP to %d.", sp); session->game.commanderSession.currentCommander.info.currentSP = sp; zoneBuilderUpdateSP(session->game.commanderSession.currentCommander.info.pcId, sp, replyMsg); } free(arg); } } void adminCmdSetLevel(Worker *self, Session *session, char *args, zmsg_t *replyMsg) { if (strlen (args) == 0) { info("Set level needs a argument!"); } else { char **arg; int argc; info("Set level with argument: %s", args); arg = strSplit(args, ' '); argc = 0; while (arg[++argc] != NULL); if (argc != 1) { info("Wrong number of arguments, must be 1."); } else { uint32_t level = atoi(arg[0]); info("Setting level to %d.", level); session->game.commanderSession.currentCommander.info.appearance.level = level; zoneBuilderPCLevelUp(session->game.commanderSession.currentCommander.info.pcId, level, replyMsg); } free(arg); } }
static int s_agent_handle_router (agent_t *self) { zframe_t *address = zframe_recv (self->router); char *hashkey = zframe_strhex (address); client_t *client = (client_t *) zhash_lookup (self->clients, hashkey); if (client == NULL && self->nbr_pending < self->max_pending) { client = client_new (self, address); client_set_pending (client); curve_codec_set_verbose (client->codec, self->verbose); zhash_foreach (self->metadata, client_set_metadata, client); zhash_insert (self->clients, hashkey, client); zhash_freefn (self->clients, hashkey, client_free); } free (hashkey); zframe_destroy (&address); // If we're overloaded, discard client request without any further // ado. The client will have to detect this and retry later. // TODO: retry in client side to handle overloaded servers. if (client == NULL) return 0; // If not yet connected, process one command frame // We always read one request, and send one reply if (client->state == pending) { zframe_t *input = zframe_recv (self->router); zframe_t *output = curve_codec_execute (client->codec, &input); if (output) { zframe_send (&client->address, self->router, ZFRAME_MORE + ZFRAME_REUSE); zframe_send (&output, self->router, 0); if (curve_codec_connected (client->codec)) client_set_connected (client); } else client_set_exception (client); } else // If connected, process one message frame // We will queue message frames in the client until we get a // whole message ready to deliver up the data socket -- frames // from different clients will be randomly intermixed. if (client->state == connected) { zframe_t *encrypted = zframe_recv (self->router); zframe_t *cleartext = curve_codec_decode (client->codec, &encrypted); if (cleartext) { if (client->incoming == NULL) client->incoming = zmsg_new (); zmsg_add (client->incoming, cleartext); if (!zframe_more (cleartext)) { zmsg_pushstr (client->incoming, client->hashkey); zmsg_send (&client->incoming, self->data); } } else client_set_exception (client); } // If client is misbehaving, remove it if (client->state == exception) zhash_delete (self->clients, client->hashkey); return 0; }
int rrwrk_start(rrwrk_t *self, wrk_task_fn *cb) { self->heartbeat_at = zclock_time() + self->heartbeat; self->cb = cb; //** Start task thread and wait for synchronization signal self->pipe = zthread_fork(self->ctx, rrtask_manager_fn, (void *)self); assert(self->pipe); free(zstr_recv(self->pipe)); //self->liveness = HEARTBEAT_LIVENESS; //** Don't do reconnect before the first connection established while(!zctx_interrupted) { zmq_pollitem_t items[] = {{self->worker, 0, ZMQ_POLLIN, 0}, {self->pipe, 0, ZMQ_POLLIN, 0}}; //** Be aware: this must be within while loop!! int rc = zmq_poll(items, 2, self->heartbeat * ZMQ_POLL_MSEC); if (rc == -1) break; //** Interrupted if (items[0].revents & ZMQ_POLLIN) { //** Data from broker is ready zmsg_t *msg = zmsg_recv(self->worker); if (!msg) break; //** Interrupted. Need to do more research to confirm it self->liveness = HEARTBEAT_LIVENESS; self->last_heartbeat = zclock_time(); //** Dont try to handle errors, just assert noisily assert(zmsg_size(msg) >= 3); //** empty + header + command + ... zframe_t *empty = zmsg_pop(msg); assert(zframe_streq(empty, "")); zframe_destroy(&empty); zframe_t *header = zmsg_pop(msg); assert(zframe_streq(header, RR_WORKER)); zframe_destroy(&header); zframe_t *command = zmsg_pop(msg); if (zframe_streq(command, RRWRK_REQUEST)) { assert(zmsg_size(msg) == 3); //** UUID + SOURCE + INPUT DATA self->total_received++; zmq_pollitem_t item = {self->pipe, 0, ZMQ_POLLOUT, 0}; int rc = zmq_poll(&item, 1, 0); assert(rc != -1); if (item.revents & ZMQ_POLLOUT) { //** Dispatch it if worker is ready //** Send task to task manager zmsg_send(&msg, self->pipe); } else { //** Otherwise put it on waiting list zlist_push(self->data, zmsg_dup(msg)); } } else if (zframe_streq(command, RRWRK_HEARTBEAT)) { ; //** Do nothing for heartbeat } else if (zframe_streq(command, RRWRK_DISCONNECT)) { rrwrk_connect_to_broker(self); } else { log_printf(0, "E: invalid input message\n"); } zframe_destroy(&command); zmsg_destroy(&msg); } else if ((zclock_time() - self->heartbeat) > self->last_heartbeat) { if(--self->liveness == 0) { rrwrk_print(self); log_printf(0, "W: Disconnected from broker - retrying ...\n"); rrwrk_print(self); zclock_sleep(self->reconnect); rrwrk_connect_to_broker(self); } } if (items[1].revents & ZMQ_POLLIN) { //** Data from pipe is ready zmsg_t *output = zmsg_recv(self->pipe); assert(zmsg_size(output) == 3); //** UUID + SOURCE + DATA self->total_finished++; zmsg_t *reply = zmsg_new(); //** Adds UUID + SOURCE to reply message zframe_t *uuid = zframe_dup(zmsg_first(output)); zframe_t *source = zframe_dup(zmsg_next(output)); zmsg_add(reply, uuid); zmsg_add(reply, source); //** Sends reply to broker rrwrk_send_to_broker(self, RRWRK_REPLY, reply); //** Sends output to sinker //zmsg_send(&output, self->sender); rrwrk_send_to_sinker(self, RRWRK_OUTPUT, output); zmsg_destroy(&output); zmsg_destroy(&reply); } //** Dispatch task if any while (true) { zmq_pollitem_t pipe_write = {self->pipe, 0, ZMQ_POLLOUT, 0}; zmq_poll(&pipe_write, 1, 0); if ((pipe_write.revents & ZMQ_POLLOUT) && (zlist_size(self->data))) { zmsg_t* data = (zmsg_t *)zlist_pop(self->data); zmsg_send(&data, self->pipe); printf("Dispatched one task.\n"); } else break; } //** Send HEARTBEAT if it's time if (zclock_time() > self->heartbeat_at) { rrwrk_print(self); rrwrk_send_to_broker(self, RRWRK_HEARTBEAT, NULL); self->heartbeat_at = zclock_time() + self->heartbeat; } } if (zctx_interrupted) log_printf(0, "W: interrupt received. Killing worker...\n"); return -1; }
zre_msg_t * zre_msg_decode (zmsg_t **msg_p, int socket_type) { assert (msg_p); zmsg_t *msg = *msg_p; if (msg == NULL) return NULL; zre_msg_t *self = zre_msg_new (0); // If message came from a router socket, first frame is routing_id if (socket_type == ZMQ_ROUTER) { self->routing_id = zmsg_pop (msg); // If message was not valid, forget about it if (!self->routing_id || !zmsg_next (msg)) { zre_msg_destroy (&self); return (NULL); // Malformed or empty } } // Read and parse command in frame zframe_t *frame = zmsg_pop (msg); if (!frame) goto empty; // Malformed or empty // Get and check protocol signature self->needle = zframe_data (frame); self->ceiling = self->needle + zframe_size (frame); uint16_t signature; GET_NUMBER2 (signature); if (signature != (0xAAA0 | 1)) goto empty; // Invalid signature // Get message id and parse per message type GET_NUMBER1 (self->id); switch (self->id) { case ZRE_MSG_HELLO: GET_NUMBER2 (self->sequence); GET_STRING (self->ipaddress); GET_NUMBER2 (self->mailbox); { size_t list_size; GET_NUMBER4 (list_size); self->groups = zlist_new (); zlist_autofree (self->groups); while (list_size--) { char *string; GET_LONGSTR (string); zlist_append (self->groups, string); free (string); } } GET_NUMBER1 (self->status); { size_t hash_size; GET_NUMBER4 (hash_size); self->headers = zhash_new (); zhash_autofree (self->headers); while (hash_size--) { char *key, *value; GET_STRING (key); GET_LONGSTR (value); zhash_insert (self->headers, key, value); free (key); free (value); } } break; case ZRE_MSG_WHISPER: GET_NUMBER2 (self->sequence); // Get zero or more remaining frames, leaving current // frame untouched self->content = zmsg_new (); while (zmsg_size (msg)) zmsg_add (self->content, zmsg_pop (msg)); break; case ZRE_MSG_SHOUT: GET_NUMBER2 (self->sequence); GET_STRING (self->group); // Get zero or more remaining frames, leaving current // frame untouched self->content = zmsg_new (); while (zmsg_size (msg)) zmsg_add (self->content, zmsg_pop (msg)); break; case ZRE_MSG_JOIN: GET_NUMBER2 (self->sequence); GET_STRING (self->group); GET_NUMBER1 (self->status); break; case ZRE_MSG_LEAVE: GET_NUMBER2 (self->sequence); GET_STRING (self->group); GET_NUMBER1 (self->status); break; case ZRE_MSG_PING: GET_NUMBER2 (self->sequence); break; case ZRE_MSG_PING_OK: GET_NUMBER2 (self->sequence); break; default: goto malformed; } // Successful return zframe_destroy (&frame); zmsg_destroy (msg_p); return self; // Error returns malformed: printf ("E: malformed message '%d'\n", self->id); empty: zframe_destroy (&frame); zmsg_destroy (msg_p); zre_msg_destroy (&self); return (NULL); }