static void process_reply( pn_messenger_t *messenger, pn_message_t *message) { int rc; pn_data_t *body = pn_message_body(message); pn_bytes_t m_type; pn_bytes_t m_command; pn_bytes_t m_value; pn_bytes_t m_status; bool duplicate = false; rc = pn_data_scan( body, "{.S.S.S.S}", &m_type, &m_command, &m_value, &m_status ); check( rc == 0, "Failed to decode response message" ); check(strncmp("response", m_type.start, m_type.size) == 0, "Unknown message type received"); if (strncmp("DUPLICATE", m_status.start, m_status.size) == 0) { LOG( "Server detected duplicate request!\n" ); duplicate = true; } else if (strncmp("OK", m_status.start, m_status.size)) { fprintf( stderr, "Request failed - error: %.*s\n", (int)m_status.size, m_status.start ); return; } fprintf( stdout, "Fortune%s: \"%.*s\"%s\n", strncmp("set", m_command.start, m_command.size) == 0 ? " set to" : "", (int)m_value.size, m_value.start, duplicate ? " (duplicate detected by server)" : "" ); }
static pn_message_t *build_request_message(pn_message_t *message, const char *command, const char *to, const char *reply_to, const char *new_fortune, unsigned int ttl) { int rc; pn_message_set_address( message, to ); if (reply_to) { LOG("setting reply-to %s\n", reply_to); rc = pn_message_set_reply_to( message, reply_to ); check(rc == 0, "pn_message_set_reply_to() failed"); } pn_message_set_delivery_count( message, 0 ); if (ttl) pn_message_set_ttl( message, ttl * 1000 ); pn_data_t *body = pn_message_body(message); pn_data_clear( body ); rc = pn_data_fill( body, "{SSSSSS}", "type", "request", "command", command, "value", (new_fortune) ? new_fortune : "" ); check( rc == 0, "Failure to create request message" ); return message; }
void sender_context_init(sender_context_t *sc, Options_t *opts, Statistics_t *stats) { sc->opts = opts; sc->stats = stats; sc->sent = 0; sc->received = 0; sc->id.type = PN_ULONG; sc->reply_message = 0; // 4096 extra bytes should easily cover the message metadata sc->encoded_data_size = sc->opts->msg_size + 4096; sc->encoded_data = (char *)calloc(1, sc->encoded_data_size); check(sc->encoded_data, "failed to allocate encoding buffer"); sc->container_id = pn_string("reactor-send"); // prefer uuid-like name sc->reply_message = (sc->opts->get_replies) ? pn_message() : 0; sc->message = pn_message(); check(sc->message, "failed to allocate a message"); pn_string_t *rpto = pn_string("amqp://"); pn_string_addf(rpto, "%s", pn_string_get(sc->container_id)); pn_message_set_reply_to(sc->message, pn_string_get(rpto)); pn_free(rpto); pn_data_t *body = pn_message_body(sc->message); // borrow the encoding buffer this one time char *data = sc->encoded_data; pn_data_put_binary(body, pn_bytes(sc->opts->msg_size, data)); check(sc->opts->targets.count > 0, "no specified address"); sc->send_url = pn_url_parse(sc->opts->targets.addresses[0]); const char *host = pn_url_get_host(sc->send_url); const char *port = pn_url_get_port(sc->send_url); sc->hostname = pn_string(host); if (port && strlen(port)) pn_string_addf(sc->hostname, ":%s", port); }
void process_flow(ldp_connection_t *conn, pn_event_t *event) { fprintf(stderr, "flow event %s\n", pn_event_type_name(pn_event_type(event))); pn_link_t *sender = pn_event_link(event); pn_message_t *message = pn_message(); pn_message_set_address(message, "amqp://foo/bar"); pn_data_t *body = pn_message_body(message); char *msgtext = "hello world!"; pn_data_put_string(body, pn_bytes(strlen(msgtext), msgtext)); pn_buffer_t *buffer = pn_buffer(1000); char *encoded = pn_buffer_bytes(buffer).start; size_t size = pn_buffer_capacity(buffer); int err = pn_message_encode(message, encoded, &size); if (err) { fprintf(stderr, "trouble encoding message\n"); } else { char tag[8]; static uint64_t next_tag; *((uint64_t*)tag) = ++next_tag; pn_delivery_t *d = pn_delivery(sender, pn_dtag(tag, 8)); pn_link_send(sender, encoded, size); pn_link_advance(sender); } pn_buffer_free(buffer); pn_message_free(message); }
/* Test sending/receiving a message in chunks */ static void test_message_stream(test_t *t) { test_proactor_t tps[] ={ test_proactor(t, message_stream_handler), test_proactor(t, message_stream_handler) }; pn_proactor_t *client = tps[0].proactor; pn_listener_t *l = test_listen(&tps[1], ""); struct message_stream_context ctx = { 0 }; tps[0].handler.context = &ctx; tps[1].handler.context = &ctx; /* Encode a large (not very) message to send in chunks */ char *body = (char*)malloc(BODY); memset(body, 'x', BODY); pn_message_t *m = pn_message(); pn_data_put_binary(pn_message_body(m), pn_bytes(BODY, body)); free(body); ctx.size = message_encode(m, &ctx.send_buf); pn_message_free(m); pn_connection_t *c = pn_connection(); pn_proactor_connect2(client, c, NULL, listener_info(l).connect); pn_session_t *ssn = pn_session(c); pn_session_open(ssn); pn_link_t *snd = pn_sender(ssn, "x"); pn_link_open(snd); TEST_PROACTORS_RUN_UNTIL(tps, PN_LINK_FLOW); /* Send and receive the message in chunks */ do { pn_connection_wake(c); /* Initiate send/receive of one chunk */ do { /* May be multiple receives for one send */ TEST_PROACTORS_RUN_UNTIL(tps, PN_DELIVERY); } while (ctx.received < ctx.sent); } while (!ctx.complete); TEST_CHECK(t, ctx.received == ctx.size); TEST_CHECK(t, ctx.sent == ctx.size); TEST_CHECK(t, !memcmp(ctx.send_buf.start, ctx.recv_buf.start, ctx.size)); free(ctx.send_buf.start); free(ctx.recv_buf.start); TEST_PROACTORS_DESTROY(tps); }
void amqp::Sender::send(IMessage const &message, Address const &address) { pn_data_t *pnmessage_body = NULL; pn_message_t *pnmessage = pn_message(); if (pnmessage == NULL) { throw std::exception("ERROR: Message could not be created."); } pn_message_set_address(pnmessage, address.toString().c_str()); _addMetaToMessage(pnmessage, message); pnmessage_body = pn_message_body(pnmessage); pn_data_put_binary(pnmessage_body, pn_bytes(message.getSize(), message.getBytes())); pn_messenger_put(m_messenger, pnmessage); if (isError()) { _throwError(); } // To avoid traffic flud and speed up the solution better to use blocking scokets in tracking mode if (isTraking()) { Log("Sending messages to %s\n", address.toString().c_str()); m_tracker = pn_messenger_outgoing_tracker(m_messenger); pn_messenger_send(m_messenger, -1); // sync } else { pn_messenger_send(m_messenger, 1); // async } if (isError()) { _throwError(); } _checkTracking(); pn_message_free(pnmessage); }
int sendMessage(pn_messenger_t * messenger) { //char * address = (char *) "amqps://{SAS Key Name}:{SAS key}@{namespace name}.servicebus.windows.net/{event hub name}"; char * address = (char *) "amqps://*****:*****@kelvin-flight.servicebus.windows.net/example"; char * msgtext = (char *) "Hello from C!"; pn_message_t * message; pn_data_t * body; message = pn_message(); pn_message_set_address(message, address); pn_message_set_content_type(message, (char*) "application/octect-stream"); pn_message_set_inferred(message, true); body = pn_message_body(message); pn_data_put_binary(body, pn_bytes(strlen(msgtext), msgtext)); pn_messenger_put(messenger, message); check(messenger); pn_messenger_send(messenger, 1); check(messenger); pn_message_free(message); }
mama_status qpidBridgeMsgCodec_pack (msgBridge bridgeMessage, mamaMsg target, pn_message_t** protonMessage) { pn_data_t* properties = NULL; pn_data_t* body = NULL; mamaPayloadType payloadType = MAMA_PAYLOAD_UNKNOWN; const void* buffer = NULL; mama_size_t bufferLen = 0; char* subject = NULL; char* destination = NULL; char* inboxName = NULL; char* replyTo = NULL; char* targetSubject = NULL; mama_status status = MAMA_STATUS_OK; qpidMsgType type = QPID_MSG_PUB_SUB; if (NULL == bridgeMessage || NULL == target) { return MAMA_STATUS_NULL_ARG; } /* Get the underlying payload type */ mamaMsg_getPayloadType (target, &payloadType); /* If this is a qpid payload, we don't need to serialize */ if (MAMA_PAYLOAD_QPID == payloadType) { /* This will extract only the underlying handle */ mamaMsgImpl_getPayloadBuffer (target, &buffer, &bufferLen); /* Don't use function's proton message - use the one just extracted */ *protonMessage = (pn_message_t*) buffer; } else { const void* buffer = NULL; mama_size_t bufferLen = 0; /* This will extract a serialized version of the payload */ mamaMsg_getByteBuffer (target, &buffer, &bufferLen); /* Use the function's proton message if this is not a qpid payload */ body = pn_message_body (*protonMessage); pn_data_put_binary (body, pn_bytes(bufferLen, (char*)buffer)); } /* Set the subject for the middleware according to the bridge msg */ status = qpidBridgeMamaMsgImpl_getSendSubject (bridgeMessage, &subject); if (MAMA_STATUS_OK != status) { return status; } pn_message_set_subject (*protonMessage, subject); /* Set the URL destination for the middleware according to the bridge msg */ status = qpidBridgeMamaMsgImpl_getDestination (bridgeMessage, &destination); if (MAMA_STATUS_OK != status) { return status; } pn_message_set_address (*protonMessage, destination); /* Get the properties from the message */ properties = pn_message_properties (*protonMessage); /* Ensure position is at the start */ pn_data_rewind (properties); /* Main container for meta data should be a list to allow expansion */ pn_data_put_list (properties); /* Enter into the list for access to its elements */ pn_data_enter (properties); /* Set the message type for the middleware according to the bridge msg */ status = qpidBridgeMamaMsgImpl_getMsgType (bridgeMessage, &type); if (MAMA_STATUS_OK != status) { return status; } pn_data_put_ubyte (properties, type); switch (type) { /* For inbox requests, set inbox name and reply to URLs */ case QPID_MSG_INBOX_REQUEST: status = qpidBridgeMamaMsgImpl_getInboxName (bridgeMessage, &inboxName); if (MAMA_STATUS_OK != status) { return status; } pn_data_put_string (properties, pn_bytes (strlen(inboxName), inboxName)); status = qpidBridgeMamaMsgImpl_getReplyTo (bridgeMessage, &replyTo); if (MAMA_STATUS_OK != status) { return status; } pn_data_put_string (properties, pn_bytes (strlen(replyTo), replyTo)); break; /* For inbox responses, set the target subject (e.g. initial for XX) */ case QPID_MSG_INBOX_RESPONSE: status = qpidBridgeMamaMsgImpl_getTargetSubject (bridgeMessage, &targetSubject); if (MAMA_STATUS_OK != status) { return status; } pn_data_put_string (properties, pn_bytes (strlen(targetSubject), targetSubject)); break; /* The following message types require no further meta data */ case QPID_MSG_TERMINATE: case QPID_MSG_SUB_REQUEST: case QPID_MSG_PUB_SUB: default: break; } /* Exit out of the list previously entered */ pn_data_exit (properties); return MAMA_STATUS_OK; }
mama_status qpidBridgeMsgCodec_unpack (msgBridge bridgeMessage, mamaMsg target, pn_message_t* protonMessage) { pn_data_t* properties = NULL; pn_data_t* body = NULL; mama_status status = MAMA_STATUS_OK; qpidMsgType type = QPID_MSG_PUB_SUB; pn_bytes_t prop; pn_atom_t firstAtom; if (NULL == bridgeMessage || NULL == protonMessage) { return MAMA_STATUS_NULL_ARG; } /* grab the body */ body = pn_message_body (protonMessage); /* Ensure position is at the start */ pn_data_rewind (body); /* Skip over the initial null atom */ pn_data_next (body); /* Grab the first atom and see what it is - PN_LIST = qpid */ firstAtom = pn_data_get_atom (body); /* If this is a proton message */ if (PN_LIST == firstAtom.type) { status = mamaMsgImpl_setMsgBuffer (target, (void*) protonMessage, sizeof (pn_message_t*), MAMA_PAYLOAD_QPID); } /* If this looks like another MAMA payload type */ else if (PN_BINARY == firstAtom.type) { mamaPayloadType payloadType = MAMA_PAYLOAD_UNKNOWN; if (firstAtom.u.as_bytes.size == 0) { mama_log (MAMA_LOG_LEVEL_ERROR, "qpidBridgeMamaMsgImpl_unpack(): " "Binary blob of zero length found - not processing"); return MAMA_STATUS_INVALID_ARG; } /* The payload type is the first character */ payloadType = (mamaPayloadType) firstAtom.u.as_bytes.start[0]; /* Use byte buffer to populate MAMA message */ status = mamaMsgImpl_setMsgBuffer ( target, (void*) firstAtom.u.as_bytes.start, (mama_size_t) firstAtom.u.as_bytes.size, payloadType); if (MAMA_STATUS_OK != status) { mama_log (MAMA_LOG_LEVEL_ERROR, "qpidBridgeMamaMsgImpl_unpack(): " "Could not set msg buffer. Cannot unpack (%s).", mamaStatus_stringForStatus (status)); return status; } } /* If this looks like something we cannot handle */ else { mama_log (MAMA_LOG_LEVEL_ERROR, "qpidBridgeMamaMsgImpl_unpack(): " "Unable to unpack data received: incompatible format %s", pn_type_name (firstAtom.type)); } /* Get the properties */ properties = pn_message_properties (protonMessage); /* Ensure position is at the start */ pn_data_rewind (properties); /* Skip over the initial null atom */ pn_data_next (properties); /* Main container should be a list to allow expansion */ pn_data_get_list (properties); pn_data_enter (properties); /* Get the message type out */ pn_data_next (properties); type = (qpidMsgType) pn_data_get_ubyte (properties); qpidBridgeMamaMsgImpl_setMsgType (bridgeMessage, type); switch (type) { case QPID_MSG_INBOX_REQUEST: /* Move onto inbox name and extract / copy */ pn_data_next (properties); prop = pn_data_get_string (properties); status = qpidBridgeMamaMsgImpl_setInboxName (bridgeMessage, prop.start); if (MAMA_STATUS_OK != status) { return status; } /* Move onto reply to url and extract / copy */ pn_data_next (properties); prop = pn_data_get_string (properties); status = qpidBridgeMamaMsgImpl_setReplyTo (bridgeMessage, prop.start); if (MAMA_STATUS_OK != status) { return status; } break; case QPID_MSG_INBOX_RESPONSE: /* Move onto target subject and extract / copy */ pn_data_next (properties); prop = pn_data_get_string (properties); status = qpidBridgeMamaMsgImpl_setTargetSubject (bridgeMessage, prop.start); if (MAMA_STATUS_OK != status) { return status; } break; /* The following message types require no further meta data */ case QPID_MSG_TERMINATE: case QPID_MSG_SUB_REQUEST: case QPID_MSG_PUB_SUB: default: break; } pn_data_exit (properties); return status; }
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; }
mama_status qpidBridgeMamaSubscription_create (subscriptionBridge* subscriber, const char* source, const char* symbol, mamaTransport tport, mamaQueue queue, mamaMsgCallbacks callback, mamaSubscription subscription, void* closure) { qpidSubscription* impl = NULL; qpidTransportBridge* transport = NULL; mama_status status = MAMA_STATUS_OK; pn_data_t* data = NULL; if ( NULL == subscriber || NULL == subscription || NULL == tport ) { mama_log (MAMA_LOG_LEVEL_ERROR, "qpidBridgeMamaSubscription_create(): something NULL"); return MAMA_STATUS_NULL_ARG; } status = mamaTransport_getBridgeTransport (tport, (transportBridge*) &transport); if (MAMA_STATUS_OK != status || NULL == transport) { mama_log (MAMA_LOG_LEVEL_ERROR, "qpidBridgeMamaSubscription_create(): something NULL"); return MAMA_STATUS_NULL_ARG; } /* Allocate memory for qpid subscription implementation */ impl = (qpidSubscription*) calloc (1, sizeof (qpidSubscription)); if (NULL == impl) { return MAMA_STATUS_NOMEM; } mamaQueue_getNativeHandle(queue, &impl->mQpidQueue); impl->mMamaCallback = callback; impl->mMamaSubscription = subscription; impl->mMamaQueue = queue; impl->mTransport = (mamaTransport)transport; impl->mSymbol = symbol; impl->mClosure = closure; impl->mIsNotMuted = 1; impl->mIsTportDisconnected = 1; impl->mSubjectKey = NULL; /* Use a standard centralized method to determine a topic key */ qpidBridgeMamaSubscriptionImpl_generateSubjectKey (NULL, source, symbol, &impl->mSubjectKey); /* Register the endpoint */ endpointPool_registerWithoutIdentifier (transport->mSubEndpoints, impl->mSubjectKey, &impl->mEndpointIdentifier, impl); /* Notify the publisher that you have an interest in this topic */ pn_message_clear (transport->mMsg); /* Set the message meta data to reflect a subscription request */ qpidBridgePublisherImpl_setMessageType (transport->mMsg, QPID_MSG_SUB_REQUEST); /* Set the outgoing address as provided by the transport configuration */ pn_message_set_address (transport->mMsg, transport->mOutgoingAddress); /* Set the reply address */ pn_message_set_reply_to (transport->mMsg, transport->mReplyAddress); /* Get the proton message's body data for writing */ data = pn_message_body (transport->mMsg); /* Add in the subject key as the only string inside */ pn_data_put_string (data, pn_bytes (strlen (impl->mSubjectKey), impl->mSubjectKey)); /* Send out the subscription registration of interest message */ if (NULL != transport->mOutgoingAddress) { pn_messenger_put (transport->mOutgoing, transport->mMsg); if (0 != PN_MESSENGER_SEND (transport->mOutgoing)) { const char* qpid_error = PN_MESSENGER_ERROR (transport->mOutgoing); mama_log (MAMA_LOG_LEVEL_SEVERE, "qpidBridgeMamaSubscription_create(): " "pn_messenger_send Error:[%s]", qpid_error); return MAMA_STATUS_PLATFORM; } } mama_log (MAMA_LOG_LEVEL_FINEST, "qpidBridgeMamaSubscription_create(): " "created interest for %s.", impl->mSubjectKey); /* Mark this subscription as valid */ impl->mIsValid = 1; *subscriber = (subscriptionBridge) impl; return MAMA_STATUS_OK; }
impl(pn_message_t *msg) { body.reset(pn_message_body(msg)); properties.reset(pn_message_properties(msg)); annotations.reset(pn_message_annotations(msg)); instructions.reset(pn_message_instructions(msg)); }
int main(int argc, char** argv) { const char *address = "localhost"; const char *msgtext = "Hello World!"; const char *container = "SendExample"; int c; pn_message_t *message = NULL; pn_data_t *body = NULL; pn_reactor_t *reactor = NULL; pn_url_t *url = NULL; pn_connection_t *conn = NULL; /* Create a handler for the connection's events. event_handler() will be * called for each event and delete_handler will be called when the * connection is released. The handler will allocate an app_data_t * instance which can be accessed when the event_handler is called. */ pn_handler_t *handler = pn_handler_new(event_handler, sizeof(app_data_t), delete_handler); /* set up the application data with defaults */ app_data_t *app_data = GET_APP_DATA(handler); memset(app_data, 0, sizeof(app_data_t)); app_data->count = 1; app_data->target = "examples"; /* Attach the pn_handshaker() handler. This handler deals with endpoint * events from the peer so we don't have to. */ { pn_handler_t *handshaker = pn_handshaker(); pn_handler_add(handler, handshaker); pn_decref(handshaker); } /* command line options */ opterr = 0; while((c = getopt(argc, argv, "i:a:c:t:nhq")) != -1) { switch(c) { case 'h': usage(); break; case 'a': address = optarg; break; case 'c': app_data->count = atoi(optarg); if (app_data->count < 1) usage(); break; case 't': app_data->target = optarg; break; case 'n': app_data->anon = 1; break; case 'i': container = optarg; break; case 'q': quiet = 1; break; default: usage(); break; } } if (optind < argc) msgtext = argv[optind]; // create a single message and pre-encode it so we only have to do that // once. All transmits will use the same pre-encoded message simply for // speed. // message = pn_message(); pn_message_set_address(message, app_data->target); body = pn_message_body(message); pn_data_clear(body); // This message's body contains a single string if (pn_data_fill(body, "S", msgtext)) { fprintf(stderr, "Error building message!\n"); exit(1); } pn_data_rewind(body); { // encode the message, expanding the encode buffer as needed // size_t len = 128; char *buf = (char *)malloc(len); int rc = 0; do { rc = pn_message_encode(message, buf, &len); if (rc == PN_OVERFLOW) { free(buf); len *= 2; buf = (char *)malloc(len); } } while (rc == PN_OVERFLOW); app_data->msg_len = len; app_data->msg_data = buf; } pn_decref(message); // message no longer needed reactor = pn_reactor(); url = pn_url_parse(address); if (url == NULL) { fprintf(stderr, "Invalid host address %s\n", address); exit(1); } conn = pn_reactor_connection_to_host(reactor, pn_url_get_host(url), pn_url_get_port(url), handler); pn_decref(url); pn_decref(handler); // the container name should be unique for each client pn_connection_set_container(conn, container); // wait up to 5 seconds for activity before returning from // pn_reactor_process() pn_reactor_set_timeout(reactor, 5000); pn_reactor_start(reactor); while (pn_reactor_process(reactor)) { /* Returns 'true' until the connection is shut down. * pn_reactor_process() will return true at least once every 5 seconds * (due to the timeout). If no timeout was configured, * pn_reactor_process() returns as soon as it finishes processing all * pending I/O and events. Once the connection has closed, * pn_reactor_process() will return false. */ } pn_decref(reactor); return 0; }
int main(int argc, char** argv) { char* certificate = NULL; char* privatekey = NULL; char* password = NULL; char* address = (char *) "amqp://~0.0.0.0"; int c; pn_message_t * message; pn_messenger_t * messenger; message = pn_message(); messenger = pn_messenger(NULL); opterr = 0; while((c = getopt(argc, argv, "hc:k:p:")) != -1) { switch(c) { case 'h': usage(); break; case 'c': certificate = optarg; break; case 'k': privatekey = optarg; break; case 'p': password = optarg; break; case '?': if(optopt == 'c' || optopt == 'k' || optopt == 'p') { fprintf(stderr, "Option -%c requires an argument.\n", optopt); } else if(isprint(optopt)) { fprintf(stderr, "Unknown option `-%c'.\n", optopt); } else { fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt); } return 1; default: abort(); } } if (optind < argc) { address = argv[optind]; } /* load the various command line options if they're set */ if(certificate) { pn_messenger_set_certificate(messenger, certificate); } if(privatekey) { pn_messenger_set_private_key(messenger, privatekey); } if(password) { pn_messenger_set_password(messenger, password); } pn_messenger_start(messenger); check(messenger); pn_messenger_subscribe(messenger, address); check(messenger); for(;;) { pn_messenger_recv(messenger, 1024); check(messenger); while(pn_messenger_incoming(messenger)) { pn_messenger_get(messenger, message); check(messenger); { char buffer[1024]; size_t buffsize = sizeof(buffer); const char* subject = pn_message_get_subject(message); pn_data_t *body = pn_message_body(message); pn_data_format(body, buffer, &buffsize); printf("Address: %s\n", pn_message_get_address(message)); printf("Subject: %s\n", subject ? subject : "(no subject)"); printf("Content: %s\n", buffer); } } } return 0; }