int main(int argc, char** argv) { Options_t opts; Statistics_t stats; uint64_t sent = 0; uint64_t received = 0; int target_index = 0; int rc; pn_message_t *message = 0; pn_message_t *reply_message = 0; pn_messenger_t *messenger = 0; parse_options( argc, argv, &opts ); messenger = pn_messenger( opts.name ); if (opts.certificate) { rc = pn_messenger_set_certificate(messenger, opts.certificate); check( rc == 0, "Failed to set certificate" ); } if (opts.privatekey) { rc = pn_messenger_set_private_key(messenger, opts.privatekey); check( rc == 0, "Failed to set private key" ); } if (opts.password) { rc = pn_messenger_set_password(messenger, opts.password); free(opts.password); check( rc == 0, "Failed to set password" ); } if (opts.ca_db) { rc = pn_messenger_set_trusted_certificates(messenger, opts.ca_db); check( rc == 0, "Failed to set trusted CA database" ); } if (opts.outgoing_window) { pn_messenger_set_outgoing_window( messenger, opts.outgoing_window ); } pn_messenger_set_timeout( messenger, opts.timeout ); pn_messenger_start(messenger); message = pn_message(); check(message, "failed to allocate a message"); pn_message_set_reply_to(message, "~"); pn_data_t *body = pn_message_body(message); char *data = (char *)calloc(1, opts.msg_size); pn_data_put_binary(body, pn_bytes(opts.msg_size, data)); free(data); pn_atom_t id; id.type = PN_ULONG; #if 0 // TODO: how do we effectively benchmark header processing overhead??? pn_data_t *props = pn_message_properties(message); pn_data_put_map(props); pn_data_enter(props); // //pn_data_put_string(props, pn_bytes(6, "string")); //pn_data_put_string(props, pn_bytes(10, "this is awkward")); // //pn_data_put_string(props, pn_bytes(4, "long")); pn_data_put_long(props, 12345); // //pn_data_put_string(props, pn_bytes(9, "timestamp")); pn_data_put_timestamp(props, (pn_timestamp_t) 54321); pn_data_exit(props); #endif const int get_replies = opts.get_replies; if (get_replies) { // disable the timeout so that pn_messenger_recv() won't block reply_message = pn_message(); check(reply_message, "failed to allocate a message"); } statistics_start( &stats ); while (!opts.msg_count || (sent < opts.msg_count)) { // setup the message to send pn_message_set_address(message, opts.targets.addresses[target_index]); target_index = NEXT_ADDRESS(opts.targets, target_index); id.u.as_ulong = sent; pn_message_set_correlation_id( message, id ); pn_message_set_creation_time( message, msgr_now() ); pn_messenger_put(messenger, message); sent++; if (opts.send_batch && (pn_messenger_outgoing(messenger) >= (int)opts.send_batch)) { if (get_replies) { while (received < sent) { // this will also transmit any pending sent messages received += process_replies( messenger, reply_message, &stats, opts.recv_count ); } } else { LOG("Calling pn_messenger_send()\n"); rc = pn_messenger_send(messenger, -1); check((rc == 0 || rc == PN_TIMEOUT), "pn_messenger_send() failed"); } } check_messenger(messenger); } LOG("Messages received=%llu sent=%llu\n", received, sent); if (get_replies) { // wait for the last of the replies while (received < sent) { int count = process_replies( messenger, reply_message, &stats, opts.recv_count ); check( count > 0 || (opts.timeout == 0), "Error: timed out waiting for reply messages\n"); received += count; LOG("Messages received=%llu sent=%llu\n", received, sent); } } else if (pn_messenger_outgoing(messenger) > 0) { LOG("Calling pn_messenger_send()\n"); rc = pn_messenger_send(messenger, -1); check(rc == 0, "pn_messenger_send() failed"); } rc = pn_messenger_stop(messenger); check(rc == 0, "pn_messenger_stop() failed"); check_messenger(messenger); statistics_report( &stats, sent, received ); pn_messenger_free(messenger); pn_message_free(message); if (reply_message) pn_message_free( reply_message ); addresses_free( &opts.targets ); return 0; }
int main(int argc, char** argv) { Options_t opts; Statistics_t stats; uint64_t sent = 0; uint64_t received = 0; int forwarding_index = 0; int rc; pn_message_t *message; pn_messenger_t *messenger; parse_options( argc, argv, &opts ); const int forward = opts.forwarding_targets.count != 0; message = pn_message(); messenger = pn_messenger( opts.name ); /* load the various command line options if they're set */ if (opts.certificate) { rc = pn_messenger_set_certificate(messenger, opts.certificate); check_messenger(messenger); check( rc == 0, "Failed to set certificate" ); } if (opts.privatekey) { rc = pn_messenger_set_private_key(messenger, opts.privatekey); check_messenger(messenger); check( rc == 0, "Failed to set private key" ); } if (opts.password) { rc = pn_messenger_set_password(messenger, opts.password); check_messenger(messenger); check( rc == 0, "Failed to set password" ); } if (opts.ca_db) { rc = pn_messenger_set_trusted_certificates(messenger, opts.ca_db); check_messenger(messenger); check( rc == 0, "Failed to set trusted CA database" ); } if (opts.incoming_window) { // RAFI: seems to cause receiver to hang: pn_messenger_set_incoming_window( messenger, opts.incoming_window ); } pn_messenger_set_timeout( messenger, opts.timeout ); pn_messenger_start(messenger); check_messenger(messenger); int i; for (i = 0; i < opts.subscriptions.count; i++) { pn_messenger_subscribe(messenger, opts.subscriptions.addresses[i]); check_messenger(messenger); LOG("Subscribing to '%s'\n", opts.subscriptions.addresses[i]); } // hack to let test scripts know when the receivers are ready (so // that the senders may be started) if (opts.ready_text) { fprintf(stdout, "%s\n", opts.ready_text); fflush(stdout); } while (!opts.msg_count || received < opts.msg_count) { LOG("Calling pn_messenger_recv(%d)\n", opts.recv_count); rc = pn_messenger_recv(messenger, opts.recv_count); check_messenger(messenger); check(rc == 0 || (opts.timeout == 0 && rc == PN_TIMEOUT), "pn_messenger_recv() failed"); // start the timer only after receiving the first msg if (received == 0) statistics_start( &stats ); LOG("Messages on incoming queue: %d\n", pn_messenger_incoming(messenger)); while (pn_messenger_incoming(messenger)) { pn_messenger_get(messenger, message); check_messenger(messenger); received++; // TODO: header decoding? // uint64_t id = pn_message_get_correlation_id( message ).u.as_ulong; statistics_msg_received( &stats, message ); if (opts.reply) { const char *reply_addr = pn_message_get_reply_to( message ); if (reply_addr) { LOG("Replying to: %s\n", reply_addr ); pn_message_set_address( message, reply_addr ); pn_message_set_creation_time( message, msgr_now() ); pn_messenger_put(messenger, message); sent++; } } if (forward) { const char *forward_addr = opts.forwarding_targets.addresses[forwarding_index]; forwarding_index = NEXT_ADDRESS(opts.forwarding_targets, forwarding_index); LOG("Forwarding to: %s\n", forward_addr ); pn_message_set_address( message, forward_addr ); pn_message_set_reply_to( message, NULL ); // else points to origin sender pn_message_set_creation_time( message, msgr_now() ); pn_messenger_put(messenger, message); sent++; } } LOG("Messages received=%llu sent=%llu\n", received, sent); } // this will flush any pending sends if (pn_messenger_outgoing(messenger) > 0) { LOG("Calling pn_messenger_send()\n"); rc = pn_messenger_send(messenger, -1); check_messenger(messenger); check(rc == 0, "pn_messenger_send() failed"); } rc = pn_messenger_stop(messenger); check(rc == 0, "pn_messenger_stop() failed"); check_messenger(messenger); statistics_report( &stats, sent, received ); pn_messenger_free(messenger); pn_message_free(message); addresses_free( &opts.subscriptions ); addresses_free( &opts.forwarding_targets ); return 0; }
int main(int argc, char** argv) { Options_t opts; int rc; pn_message_t *response_msg = pn_message(); check( response_msg, "Failed to allocate a Message"); pn_message_t *request_msg = pn_message(); check( request_msg, "Failed to allocate a Message"); pn_messenger_t *messenger = pn_messenger( 0 ); check( messenger, "Failed to allocate a Messenger"); parse_options( argc, argv, &opts ); // no need to track outstanding messages pn_messenger_set_outgoing_window( messenger, 0 ); pn_messenger_set_incoming_window( messenger, 0 ); pn_messenger_set_timeout( messenger, opts.timeout ); if (opts.gateway_addr) { LOG( "routing all messages via %s\n", opts.gateway_addr ); rc = pn_messenger_route( messenger, "*", opts.gateway_addr ); check( rc == 0, "pn_messenger_route() failed" ); } pn_messenger_start(messenger); char *reply_to = NULL; if (opts.reply_to) { LOG("subscribing to %s for replies\n", opts.reply_to); pn_messenger_subscribe(messenger, opts.reply_to); reply_to = _strdup(opts.reply_to); check( reply_to, "Out of memory" ); #if 1 // need to 'fix' the reply-to for use in the message itself: // no '~' is allowed in that case char *tilde = strstr( reply_to, "://~" ); if (tilde) { tilde += 3; // overwrite '~' memmove( tilde, tilde + 1, strlen( tilde + 1 ) + 1 ); } #endif } // Create a request message // const char *command = opts.new_fortune ? "set" : "get"; build_request_message( request_msg, opts.send_bad_msg ? "bad-command" : command, opts.address, reply_to, opts.new_fortune, opts.ttl ); // set a unique identifier for this message, so remote can // de-duplicate when we re-transmit uuid_t uuid; uuid_generate(uuid); char uuid_str[37]; uuid_unparse_upper(uuid, uuid_str); pn_data_put_string( pn_message_id( request_msg ), pn_bytes( sizeof(uuid_str), uuid_str )); // set the correlation id so we can ensure the response matches // our request. (re-use uuid just 'cause it's easy!) pn_data_put_string( pn_message_correlation_id( request_msg ), pn_bytes( sizeof(uuid_str), uuid_str )); int send_count = 0; bool done = false; // keep re-transmitting until something arrives do { LOG("sending request message...\n"); rc = pn_messenger_put( messenger, request_msg ); check(rc == 0, "pn_messenger_put() failed"); send_count++; if (opts.retry) opts.retry--; LOG("waiting for response...\n"); rc = pn_messenger_recv( messenger, -1 ); if (rc == PN_TIMEOUT) { LOG( "Timed-out waiting for a response, retransmitting...\n" ); pn_message_set_delivery_count( request_msg, send_count ); } else { check(rc == 0, "pn_messenger_recv() failed\n"); while (pn_messenger_incoming( messenger ) > 0) { rc = pn_messenger_get( messenger, response_msg ); check(rc == 0, "pn_messenger_get() failed"); LOG("response received!\n"); // validate the correlation id pn_bytes_t cid = pn_data_get_string( pn_message_correlation_id( response_msg ) ); if (cid.size == 0 || strncmp( uuid_str, cid.start, cid.size )) { LOG( "Correlation Id mismatch! Ignoring this response!\n" ); } else { process_reply( messenger, response_msg ); done = true; } } } } while (!done && opts.retry); if (!done) { fprintf( stderr, "Retries exhausted, no response received from server!\n" ); } rc = pn_messenger_stop(messenger); check(rc == 0, "pn_messenger_stop() failed"); pn_messenger_free(messenger); pn_message_free( response_msg ); pn_message_free( request_msg ); if (reply_to) free(reply_to); return 0; }