static int process_meta_information_and_handle_heartbeat(subscriber_state_t *state, zmsg_t* msg) { zframe_t *first = zmsg_first(msg); char *pub_spec = NULL; bool is_heartbeat = zframe_streq(first, "heartbeat"); msg_meta_t meta; int rc = msg_extract_meta_info(msg, &meta); if (!rc) { // dump_meta_info(&meta); if (!state->meta_info_failures++) fprintf(stderr, "[E] subscriber: received invalid meta info\n"); return is_heartbeat; } if (meta.device_number == 0) { // ignore device number 0 state->messages_dev_zero++; return is_heartbeat; } if (is_heartbeat) { if (debug) printf("received heartbeat from device %d\n", meta.device_number); zmsg_first(msg); // msg_extract_meta_info repositions the pointer, so reset zframe_t *spec_frame = zmsg_next(msg); pub_spec = zframe_strdup(spec_frame); } state->message_gap_size += device_tracker_calculate_gap(state->tracker, &meta, pub_spec); return is_heartbeat; }
static int read_zmq_message_and_forward(zloop_t *loop, zsock_t *sock, void *callback_data) { int i = 0; zmq_msg_t message_parts[4]; publisher_state_t *state = (publisher_state_t*)callback_data; void *socket = zsock_resolve(sock); // read the message parts, possibly including the message meta info while (!zsys_interrupted) { // printf("[D] receiving part %d\n", i+1); if (i>3) { zmq_msg_t dummy_msg; zmq_msg_init(&dummy_msg); zmq_recvmsg(socket, &dummy_msg, 0); zmq_msg_close(&dummy_msg); } else { zmq_msg_init(&message_parts[i]); zmq_recvmsg(socket, &message_parts[i], 0); } if (!zsocket_rcvmore(socket)) break; i++; } if (i<2) { if (!zsys_interrupted) { fprintf(stderr, "[E] received only %d message parts\n", i); } goto cleanup; } else if (i>3) { fprintf(stderr, "[E] received more than 4 message parts\n"); goto cleanup; } zmq_msg_t *body = &message_parts[2]; msg_meta_t meta = META_INFO_EMPTY; if (i==3) zmq_msg_extract_meta_info(&message_parts[3], &meta); // const char *prefix = socket == state->compressor_output ? "EXTERNAL MESSAGE" : "INTERNAL MESSAGE"; // my_zmq_msg_fprint(&message_parts[0], 3, prefix, stdout); // dump_meta_info(prefix, &meta); if (meta.created_ms) msg_meta.created_ms = meta.created_ms; else msg_meta.created_ms = global_time; size_t msg_bytes = zmq_msg_size(body); if (socket == state->compressor_output) { decompressed_messages_count++; decompressed_messages_bytes += msg_bytes; if (msg_bytes > decompressed_messages_max_bytes) decompressed_messages_max_bytes = msg_bytes; } else { received_messages_count++; received_messages_bytes += msg_bytes; if (msg_bytes > received_messages_max_bytes) received_messages_max_bytes = msg_bytes; } msg_meta.compression_method = meta.compression_method; if (meta.compression_method) { // decompress publish_on_zmq_transport(&message_parts[0], state->compressor_input, &msg_meta, 0); } else { // forward to comsumer msg_meta.sequence_number++; if (debug) { my_zmq_msg_fprint(&message_parts[0], 3, "[D]", stdout); dump_meta_info("[D]", &msg_meta); } char *pub_spec = NULL; bool is_heartbeat = zmq_msg_size(&message_parts[0]) == 9 && strncmp("heartbeat", zmq_msg_data(&message_parts[0]), 9) == 0; if (is_heartbeat) { if (debug) printf("[D] received heartbeat message from device %u\n", msg_meta.device_number); pub_spec = strndup(zmq_msg_data(&message_parts[1]), zmq_msg_size(&message_parts[1])); } device_tracker_calculate_gap(tracker, &msg_meta, pub_spec); if (!is_heartbeat) publish_on_zmq_transport(&message_parts[0], state->publisher, &msg_meta, ZMQ_DONTWAIT); } cleanup: for (;i>=0;i--) { zmq_msg_close(&message_parts[i]); } return 0; }