int RabbitInBoundConnectionPoint::ListenMessage(void** destBuffer) throw (ConnectException) { amqp_rpc_reply_t res; amqp_envelope_t envelope; amqp_maybe_release_buffers(_conn); struct timeval timeout; timeout.tv_sec = 5; timeout.tv_usec = 0; res = amqp_consume_message(_conn, &envelope, &timeout, 0); if (AMQP_RESPONSE_NORMAL == res.reply_type) { int messageLen = (int) envelope.message.body.len; void* message = malloc(messageLen); memcpy(message, envelope.message.body.bytes, messageLen); amqp_basic_ack(_conn, 1, envelope.delivery_tag, false); GetRabbitError("Ack Error"); amqp_destroy_envelope(&envelope); *destBuffer = message; return messageLen; } else { if(res.library_error != AMQP_STATUS_TIMEOUT) { LOG(ERROR) << "Error al leer de Rabbit: " << amqp_error_string2(res.library_error); throw ConnectException("Error al leer de Rabbit", true); } } return 0; }
void RabbitMQMessage::ack() { amqp_basic_ack (connection->conn, 1, envelope.delivery_tag, /* multiple */ false); acked = true; }
static void* _receiveThread(void* param) { MsgReceiver_t *receiver = (MsgReceiver_t *)param; amqp_envelope_t envelope; amqp_rpc_reply_t reply; amqp_frame_t *frame; time_t curtime; assert(receiver != NULL); LOG4CXX_DEBUG(logger, "_receiveThread: event receiver thread started"); sendLeaseRequest(receiver); curtime = getCurrentTime(); while(receiver->thread_run) { amqp_maybe_release_buffers(receiver->conn_state); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); if(getElapsedSecond(curtime, getCurrentTime()) > 60*5) { sendLeaseRequest(receiver); curtime = getCurrentTime(); } reply = amqp_consume_message(receiver->conn_state, &envelope, NULL, 0); if(reply.reply_type == AMQP_RESPONSE_NORMAL) { // call handler MsgClientCallback_t callback = receiver->callback; LOG4CXX_INFO(logger, "_receiveThread: received a message"); if(callback != NULL) { LOG4CXX_INFO(logger, "_receiveThread: received a message - calling a callback function"); callback((const char*)envelope.routing_key.bytes, envelope.routing_key.len, (const char*)envelope.message.body.bytes, envelope.message.body.len); } int ack_result = amqp_basic_ack(receiver->conn_state, receiver->channel, envelope.delivery_tag, false); if(ack_result != 0) { LOG4CXX_ERROR(logger, "_receiveThread: ack failed " << ack_result); } amqp_destroy_envelope(&envelope); } else { LOG4CXX_INFO(logger, "_receiveThread: an exception occurred"); } pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); } receiver->thread_run = false; }
void consume(int argc, char* argv[]) { if (argc < 4) { help(); } std::string queue = argv[2]; int msg_cnt = atoi(argv[3]); // 消费 amqp_basic_qos(conn, channel_id, 0, /* prefetch_size */ 1, /* prefetch_count */ 0 /* global */); amqp_basic_consume(conn, /* connection */ channel_id, /* channel */ amqp_cstring_bytes(queue.c_str()), /* queue */ amqp_cstring_bytes(int2str(channel_id).c_str()), /* consumer_tag */ 0, /* no_local */ 0, /* no_ack */ 1, /* exclusive */ amqp_empty_table /* argument */ ); int got = 0; while (got++ < msg_cnt) { amqp_envelope_t envelope; memset(&envelope, 0, sizeof(envelope)); amqp_maybe_release_buffers(conn); amqp_consume_message(conn, &envelope, NULL, 0); check_amqp_reply("amqp consume msg failed.", ""); std::string data((char*)envelope.message.body.bytes, envelope.message.body.len); int channel_id = envelope.channel; int delivery_tag = envelope.delivery_tag; std::cout << "channelid: " << channel_id << ", delivery_tag: " << delivery_tag << ", data[" << data << "]" << std::endl; amqp_basic_ack(conn, channel_id, delivery_tag, 0 /* multiple */); check_amqp_reply("amqp basic ack failed.", "amqp basic ack succ."); amqp_destroy_envelope(&envelope); // usleep(10000); } }
void Channel::BasicAck(const Envelope::DeliveryInfo &info, bool multiple) { m_impl->CheckIsConnected(); // Delivery tag is local to the channel, so its important to use // that channel, sadly this can cause the channel to throw an exception // which will show up as an unrelated exception in a different method // that actually waits for a response from the broker amqp_channel_t channel = info.delivery_channel; if (!m_impl->IsChannelOpen(channel)) { throw std::runtime_error( "The channel that the message was delivered on has been closed"); } m_impl->CheckForError( amqp_basic_ack(m_impl->m_connection, channel, info.delivery_tag, multiple)); }
int main(int argc, char const *const *argv) { char const *hostname; int port, status; char const *queuename; amqp_socket_t *socket; amqp_connection_state_t conn; if (argc < 4) { fprintf(stderr, "Usage: amqps_listenq host port queuename " "[cacert.pem [key.pem cert.pem]]\n"); return 1; } hostname = argv[1]; port = atoi(argv[2]); queuename = argv[3]; conn = amqp_new_connection(); socket = amqp_ssl_socket_new(); if (!socket) { die("creating SSL/TLS socket"); } if (argc > 4) { status = amqp_ssl_socket_set_cacert(socket, argv[4]); if (status) { die("setting CA certificate"); } } if (argc > 6) { status = amqp_ssl_socket_set_key(socket, argv[6], argv[5]); if (status) { die("setting client cert"); } } status = amqp_socket_open(socket, hostname, port); if (status) { die("opening SSL/TLS connection"); } amqp_set_socket(conn, socket); die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"), "Logging in"); amqp_channel_open(conn, 1); die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel"); amqp_basic_consume(conn, 1, amqp_cstring_bytes(queuename), amqp_empty_bytes, 0, 0, 0, amqp_empty_table); die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming"); { amqp_frame_t frame; int result; amqp_basic_deliver_t *d; amqp_basic_properties_t *p; size_t body_target; size_t body_received; while (1) { amqp_maybe_release_buffers(conn); result = amqp_simple_wait_frame(conn, &frame); printf("Result %d\n", result); if (result < 0) { break; } printf("Frame type %d, channel %d\n", frame.frame_type, frame.channel); if (frame.frame_type != AMQP_FRAME_METHOD) { continue; } printf("Method %s\n", amqp_method_name(frame.payload.method.id)); if (frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD) { continue; } d = (amqp_basic_deliver_t *) frame.payload.method.decoded; printf("Delivery %u, exchange %.*s routingkey %.*s\n", (unsigned) d->delivery_tag, (int) d->exchange.len, (char *) d->exchange.bytes, (int) d->routing_key.len, (char *) d->routing_key.bytes); result = amqp_simple_wait_frame(conn, &frame); if (result < 0) { break; } if (frame.frame_type != AMQP_FRAME_HEADER) { fprintf(stderr, "Expected header!"); abort(); } p = (amqp_basic_properties_t *) frame.payload.properties.decoded; if (p->_flags & AMQP_BASIC_CONTENT_TYPE_FLAG) { printf("Content-type: %.*s\n", (int) p->content_type.len, (char *) p->content_type.bytes); } printf("----\n"); body_target = frame.payload.properties.body_size; body_received = 0; while (body_received < body_target) { result = amqp_simple_wait_frame(conn, &frame); if (result < 0) { break; } if (frame.frame_type != AMQP_FRAME_BODY) { fprintf(stderr, "Expected body!"); abort(); } body_received += frame.payload.body_fragment.len; assert(body_received <= body_target); amqp_dump(frame.payload.body_fragment.bytes, frame.payload.body_fragment.len); } if (body_received != body_target) { /* Can only happen when amqp_simple_wait_frame returns <= 0 */ /* We break here to close the connection */ break; } amqp_basic_ack(conn, 1, d->delivery_tag, 0); } } die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel"); die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection"); die_on_error(amqp_destroy_connection(conn), "Ending connection"); return 0; }
static int lc_bus_consume_message_atomic(amqp_connection_state_t *conn, uint32_t flag, amqp_envelope_t *envelope, amqp_frame_t *frame, amqp_message_t *message, char *buf, int buf_len) { static struct timeval timeout = { tv_sec: RECV_TIMEOUT, tv_usec: 0 }; size_t body_remaining = 0, offset = 0; int res = LC_BUS_OK; amqp_basic_deliver_t *deliver = NULL; if (!envelope || !frame || !message) { return 0; } amqp_maybe_release_buffers(*conn); #if 0 amqp_consume_message(*conn, envelope, &timeout, 0); #endif res = amqp_simple_wait_frame_noblock(*conn, frame, &timeout); if (res) { LB_SYSLOG(LOG_ERR, "waiting for method frame, ret=%d.\n", res); if (res != AMQP_STATUS_TIMEOUT) { return -1; } return 0; } if (frame->frame_type != AMQP_FRAME_METHOD || frame->payload.method.id != AMQP_BASIC_DELIVER_METHOD) { LB_SYSLOG(LOG_WARNING, "got frame type 0x%X (expect AMQP_FRAME_METHOD " "0x%X) method 0x%X (expect AMQP_BASIC_DELIVER_METHOD 0x%X), " "ignore this message.\n", frame->frame_type, AMQP_FRAME_METHOD, frame->payload.method.id, AMQP_BASIC_DELIVER_METHOD); return 0; } LB_SYSLOG(LOG_INFO, "got frame type 0x%X method 0x%X.\n", frame->frame_type, frame->payload.method.id); deliver = (amqp_basic_deliver_t *)frame->payload.method.decoded; res = amqp_simple_wait_frame_noblock(*conn, frame, &timeout); if (res) { LB_SYSLOG(LOG_ERR, "waiting for header frame, ret=%d\n", res); if (res != AMQP_STATUS_TIMEOUT) { return -1; } return 0; } if (frame->frame_type != AMQP_FRAME_HEADER) { LB_SYSLOG(LOG_ERR, "got frame type 0x%X (expect " "AMQP_FRAME_HEADER 0x%X).\n", frame->frame_type, AMQP_FRAME_HEADER); return 0; } body_remaining = frame->payload.properties.body_size; LB_SYSLOG(LOG_INFO, "got frame type 0x%X (AMQP_FRAME_HEADER), " "AMQP_FRAME_BODY len %zd\n", frame->frame_type, body_remaining); while (body_remaining) { res = amqp_simple_wait_frame_noblock(*conn, frame, &timeout); if (res) { LB_SYSLOG(LOG_ERR, "waiting for body frame, ret=%d\n", res); if (res != AMQP_STATUS_TIMEOUT) { return -1; } return 0; } if (frame->frame_type != AMQP_FRAME_BODY) { LB_SYSLOG(LOG_ERR, "expected header, got frame type 0x%X\n", frame->frame_type); return 0; } LB_SYSLOG(LOG_DEBUG, "got body len %zd\n", frame->payload.body_fragment.len); memcpy(buf + offset, frame->payload.body_fragment.bytes, MINV(buf_len - offset, frame->payload.body_fragment.len)); if (buf_len - offset < frame->payload.body_fragment.len) { offset = buf_len; } else { offset += frame->payload.body_fragment.len; } body_remaining -= frame->payload.body_fragment.len; } if (flag & LC_BUS_CONSUME_WITH_ACK) { res = amqp_basic_ack( *conn, LC_BUS_CHANNEL, deliver->delivery_tag, 0 /* multiple */ ); if (res) { LB_SYSLOG(LOG_ERR, "basic ack, channel=%u ret=%d\n", LC_BUS_CHANNEL, res); return 0; } } if (buf_len == offset) { /* buffer is not enough */ return 0; } return offset; }
int main(int argc, char const * const *argv) { char const *hostname; int port; char const *queuename; char const *amqp_user; char const *amqp_passwd; amqp_frame_t frame; int result; char *ret = NULL; amqp_basic_deliver_t *d; amqp_basic_properties_t *p; size_t body_target; size_t body_received; int sockfd; amqp_connection_state_t conn; if (argc < 6) { fprintf(stderr, "Usage: amqp_listenq host port queuename user password\n"); return 1; } hostname = argv[1]; port = atoi(argv[2]); queuename = argv[3]; amqp_user = argv[4]; amqp_passwd = argv[5]; conn = amqp_new_connection(); ads_utils_error(sockfd = amqp_open_socket(hostname, port), "Opening socket"); amqp_set_sockfd(conn, sockfd); ads_utils_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, amqp_user, amqp_passwd), "Logging in"); amqp_channel_open(conn, 1); ads_utils_amqp_error(amqp_get_rpc_reply(conn), "Opening channel"); amqp_basic_consume(conn, 1, amqp_cstring_bytes(queuename), AMQP_EMPTY_BYTES, 0, 0, 0, AMQP_EMPTY_TABLE); ads_utils_amqp_error(amqp_get_rpc_reply(conn), "Consuming"); amqp_maybe_release_buffers(conn); result = amqp_simple_wait_frame(conn, &frame); if (result < 0) exit(0); if (frame.frame_type != AMQP_FRAME_METHOD) exit(0); if (frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD) exit(0); d = (amqp_basic_deliver_t *) frame.payload.method.decoded; result = amqp_simple_wait_frame(conn, &frame); if (result < 0) exit(0); if (frame.frame_type != AMQP_FRAME_HEADER) { fprintf(stderr, "Expected header!"); return 1; } p = (amqp_basic_properties_t *) frame.payload.properties.decoded; body_target = frame.payload.properties.body_size; body_received = 0; while (body_received < body_target) { result = amqp_simple_wait_frame(conn, &frame); if (result < 0) break; if (frame.frame_type != AMQP_FRAME_BODY) { fprintf(stderr, "Expected body!"); return 1; } body_received += frame.payload.body_fragment.len; assert(body_received <= body_target); ret = ads_utils_amqp_dump(frame.payload.body_fragment.bytes, frame.payload.body_fragment.len); printf("%s\n", ret); free(ret); } if (body_received != body_target) { /* Can only happen when amqp_simple_wait_frame returns <= 0 */ /* We break here to close the connection */ exit(0); } amqp_basic_ack(conn, 1, d->delivery_tag, 0); ads_utils_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel"); ads_utils_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection"); ads_utils_error(amqp_destroy_connection(conn), "Ending connection"); return 0; }
unsigned int rmq_receive() { pwr_tStatus sts; int search_remtrans = 0; remtrans_item* remtrans; amqp_rpc_reply_t ret; amqp_envelope_t envelope; struct timeval t = { 2, 0 }; rabbit_header header; int msg_received = 0; amqp_maybe_release_buffers(ctx->conn); ret = amqp_consume_message(ctx->conn, &envelope, &t, 0); switch (ret.reply_type) { case AMQP_RESPONSE_NORMAL: { break; } case AMQP_RESPONSE_NONE: return REM__SUCCESS; case AMQP_RESPONSE_SERVER_EXCEPTION: return REM__EXCEPTION; case AMQP_RESPONSE_LIBRARY_EXCEPTION: switch (ret.library_error) { case AMQP_STATUS_TIMEOUT: { amqp_destroy_envelope(&envelope); return REM__TIMEOUT; } case AMQP_STATUS_UNEXPECTED_STATE: { amqp_frame_t frame; sts = amqp_simple_wait_frame_noblock(ctx->conn, &frame, &t); if (sts == AMQP_STATUS_TIMEOUT) { printf("Wait frame timeout\n"); return REM__EXCEPTION; } else if (sts == AMQP_STATUS_OK) { if (frame.frame_type == AMQP_FRAME_METHOD) { switch (frame.payload.method.id) { case AMQP_BASIC_ACK_METHOD: printf("Basic ack method called\n"); break; case AMQP_BASIC_RETURN_METHOD: printf("Basic return method called\n"); break; case AMQP_CHANNEL_CLOSE_METHOD: printf("Channel close method called\n"); break; case AMQP_CONNECTION_CLOSE_METHOD: printf("Connection close method called\n"); break; default:; } } return REM__EXCEPTION; } else return REM__EXCEPTION; } } // Reconnect... rmq_close(1); return REM__EXCEPTION; default: printf("Unknown Reply type: %d\n", ret.reply_type); } if (debug) printf("Received message %d\n", (int)envelope.message.body.len); if (envelope.message.body.len > 0 && rn_rmq->DisableHeader) { /* Header disabled, take the first receive remtrans object */ remtrans = rn.remtrans; search_remtrans = 1; while (remtrans && search_remtrans) { /* Match? */ if (remtrans->objp->Direction == REMTRANS_IN) { search_remtrans = false; sts = RemTrans_Receive(remtrans, (char*)envelope.message.body.bytes, envelope.message.body.len); msg_received = 1; } remtrans = (remtrans_item*)remtrans->next; } if (search_remtrans) { rn_rmq->ErrCount++; errh_Info("RabbitMQ Receive no remtrans %s", rn_rmq->ReceiveQueue); } } else if (envelope.message.body.len >= sizeof(rabbit_header)) { memcpy(&header, envelope.message.body.bytes, sizeof(rabbit_header)); /* Convert the header to host byte order */ header.msg_size = ntohs(header.msg_size); header.msg_id[0] = ntohs(header.msg_id[0]); header.msg_id[1] = ntohs(header.msg_id[1]); search_remtrans = 1; remtrans = rn.remtrans; while (remtrans && search_remtrans) { if (remtrans->objp->Address[0] == header.msg_id[0] && remtrans->objp->Address[1] == header.msg_id[1] && remtrans->objp->Direction == REMTRANS_IN) { search_remtrans = false; sts = RemTrans_Receive(remtrans, (char*)envelope.message.body.bytes + sizeof(rabbit_header), envelope.message.body.len); if (sts != STATUS_OK && sts != STATUS_BUFF) errh_Error("Error from RemTrans_Receive, queue %s, status %d", rn_rmq->ReceiveQueue, sts, 0); msg_received = 1; break; } remtrans = (remtrans_item*)remtrans->next; } if (search_remtrans) { rn_rmq->ErrCount++; errh_Info("No remtrans for received message, queue %s, class %d, type %d", rn_rmq->ReceiveQueue, header.msg_id[0], header.msg_id[1]); } } if (ctx->op->Acknowledge) { if (msg_received) amqp_basic_ack(ctx->conn, ctx->channel, envelope.delivery_tag, 0); else /* Requeue the message */ amqp_basic_nack(ctx->conn, ctx->channel, envelope.delivery_tag, 0, 1); } amqp_destroy_envelope(&envelope); return sts; }
int main(int argc, char** argv) { int channel = 1, status = AMQP_STATUS_OK, cnfnlen; amqp_socket_t *socket = NULL; amqp_connection_state_t conn; amqp_rpc_reply_t ret; amqp_message_t *reply = NULL; amqp_frame_t frame; struct timeval timeout; MYSQL db_inst; char ch, *cnfname = NULL, *cnfpath = NULL; static const char* fname = "consumer.cnf"; if((c_inst = calloc(1,sizeof(CONSUMER))) == NULL){ fprintf(stderr, "Fatal Error: Cannot allocate enough memory.\n"); return 1; } if(signal(SIGINT,sighndl) == SIG_IGN){ signal(SIGINT,SIG_IGN); } while((ch = getopt(argc,argv,"c:"))!= -1){ switch(ch){ case 'c': cnfnlen = strlen(optarg); cnfpath = strdup(optarg); break; default: break; } } cnfname = calloc(cnfnlen + strlen(fname) + 1,sizeof(char)); if(cnfpath){ /**Config file path as argument*/ strcpy(cnfname,cnfpath); if(cnfpath[cnfnlen-1] != '/'){ strcat(cnfname,"/"); } } strcat(cnfname,fname); timeout.tv_sec = 1; timeout.tv_usec = 0; all_ok = 1; out_fd = NULL; /**Parse the INI file*/ if(ini_parse(cnfname,handler,NULL) < 0){ /**Try to parse a config in the same directory*/ if(ini_parse(fname,handler,NULL) < 0){ fprintf(stderr, "Fatal Error: Error parsing configuration file!\n"); goto fatal_error; } } if(out_fd == NULL){ out_fd = stdout; } fprintf(out_fd,"\n--------------------------------------------------------------\n"); /**Confirm that all parameters were in the configuration file*/ if(!c_inst->hostname||!c_inst->vhost||!c_inst->user|| !c_inst->passwd||!c_inst->dbpasswd||!c_inst->queue|| !c_inst->dbserver||!c_inst->dbname||!c_inst->dbuser){ fprintf(stderr, "Fatal Error: Inadequate configuration file!\n"); goto fatal_error; } connectToServer(&db_inst); if((conn = amqp_new_connection()) == NULL || (socket = amqp_tcp_socket_new(conn)) == NULL){ fprintf(stderr, "Fatal Error: Cannot create connection object or socket.\n"); goto fatal_error; } if(amqp_socket_open(socket, c_inst->hostname, c_inst->port)){ fprintf(stderr, "RabbitMQ Error: Cannot open socket.\n"); goto error; } ret = amqp_login(conn, c_inst->vhost, 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, c_inst->user, c_inst->passwd); if(ret.reply_type != AMQP_RESPONSE_NORMAL){ fprintf(stderr, "RabbitMQ Error: Cannot login to server.\n"); goto error; } amqp_channel_open(conn, channel); ret = amqp_get_rpc_reply(conn); if(ret.reply_type != AMQP_RESPONSE_NORMAL){ fprintf(stderr, "RabbitMQ Error: Cannot open channel.\n"); goto error; } reply = malloc(sizeof(amqp_message_t)); if(!reply){ fprintf(stderr, "Error: Cannot allocate enough memory.\n"); goto error; } amqp_basic_consume(conn,channel,amqp_cstring_bytes(c_inst->queue),amqp_empty_bytes,0,0,0,amqp_empty_table); while(all_ok){ status = amqp_simple_wait_frame_noblock(conn,&frame,&timeout); /**No frames to read from server, possibly out of messages*/ if(status == AMQP_STATUS_TIMEOUT){ sleep(timeout.tv_sec); continue; } if(frame.payload.method.id == AMQP_BASIC_DELIVER_METHOD){ amqp_basic_deliver_t* decoded = (amqp_basic_deliver_t*)frame.payload.method.decoded; amqp_read_message(conn,channel,reply,0); if(sendMessage(&db_inst,reply)){ fprintf(stderr,"RabbitMQ Error: Received malformed message.\n"); amqp_basic_reject(conn,channel,decoded->delivery_tag,0); amqp_destroy_message(reply); }else{ amqp_basic_ack(conn,channel,decoded->delivery_tag,0); amqp_destroy_message(reply); } }else{ fprintf(stderr,"RabbitMQ Error: Received method from server: %s\n",amqp_method_name(frame.payload.method.id)); all_ok = 0; goto error; } } fprintf(out_fd,"Shutting down...\n"); error: mysql_close(&db_inst); mysql_library_end(); if(c_inst && c_inst->query_stack){ while(c_inst->query_stack){ DELIVERY* d = c_inst->query_stack->next; amqp_destroy_message(c_inst->query_stack->message); free(c_inst->query_stack); c_inst->query_stack = d; } } amqp_channel_close(conn, channel, AMQP_REPLY_SUCCESS); amqp_connection_close(conn, AMQP_REPLY_SUCCESS); amqp_destroy_connection(conn); fatal_error: if(out_fd){ fclose(out_fd); } if(c_inst){ free(c_inst->hostname); free(c_inst->vhost); free(c_inst->user); free(c_inst->passwd); free(c_inst->queue); free(c_inst->dbserver); free(c_inst->dbname); free(c_inst->dbuser); free(c_inst->dbpasswd); free(c_inst); } return all_ok; }
int main(int argc, char **argv) { char const *hostname = "amqpbroker"; // amqp hostname int port = 5672; // amqp port static int verbose_flag = 0; // be verbose? static int foreground_flag = 0; static int passive = 0; // declare queue passively? static int exclusive = 0; // declare queue as exclusive? static int durable = 0; // decalre queue as durable? static int no_ack = 0; static int msg_limit = 0; // maxiumum number of messages to retrieve int const no_local = 1; // we never want to see messages we publish int c; // for option parsing char const *exchange = ""; char const *bindingkey = ""; char const *vhost = "/"; char const *username = "******"; char const *password = "******"; char const *program = NULL; char const *program_args = NULL; amqp_bytes_t queue = AMQP_EMPTY_BYTES; int sockfd; amqp_connection_state_t conn; amqp_bytes_t queuename; if (NULL != getenv("AMQP_HOST")) hostname = getenv("AMQP_HOST"); if (NULL != getenv("AMQP_PORT")) port = atoi(getenv("AMQP_PORT")); port = port > 0 ? port : 5672; // 5672 is the default amqp port if (NULL != getenv("AMQP_VHOST")) vhost = getenv("AMQP_VHOST"); if (NULL != getenv("AMQP_USER")) username = getenv("AMQP_USER"); if (NULL != getenv("AMQP_PASSWORD")) password = getenv("AMQP_PASSWORD"); if (NULL != getenv("AMQP_QUEUE")) queue = amqp_cstring_bytes(getenv("AMQP_QUEUE")); if (NULL != getenv("AMQP_QUEUE_PASSIVE")) passive = atoi(getenv("AMQP_QUEUE_PASSIVE")); if (NULL != getenv("AMQP_QUEUE_EXCLUSIVE")) exclusive = atoi(getenv("AMQP_QUEUE_EXCLUSIVE")); if (NULL != getenv("AMQP_QUEUE_DURABLE")) durable = atoi(getenv("AMQP_QUEUE_DURABLE")); if (NULL != getenv("AMQP_MSG_LIMIT")) msg_limit = atoi(getenv("AMQP_MSG_LIMIT")); msg_limit = msg_limit > 0 ? msg_limit : 0; // default to unlimited while(1) { static struct option long_options[] = { {"verbose", no_argument, &verbose_flag, 1}, {"user", required_argument, 0, 'u'}, {"password", required_argument, 0, 'p'}, {"vhost", required_argument, 0, 'v'}, {"host", required_argument, 0, 'h'}, {"port", required_argument, 0, 'P'}, {"number", required_argument, 0, 'n'}, {"foreground", no_argument, 0, 'f'}, {"passive", no_argument, &passive, 1}, {"exclusive", no_argument, &exclusive, 1}, {"durable", no_argument, &durable, 1}, {"no-ack", no_argument, &no_ack, 1}, {"execute", required_argument, 0, 'e'}, {"queue", required_argument, 0, 'q'}, {"help", no_argument, 0, '?'}, {0, 0, 0, 0} }; int option_index = 0; c = getopt_long(argc, argv, "v:h:P:u:p:n:fe:q:?", long_options, &option_index); if(c == -1) break; switch(c) { case 0: // no_argument break; case 'v': vhost = optarg; break; case 'h': hostname = optarg; break; case 'P': port = atoi(optarg); port = port > 0 ? port : 5672; // 5672 is the default amqp port break; case 'f': foreground_flag = 1; case 'n': msg_limit = atoi(optarg); msg_limit = msg_limit > 0 ? msg_limit : 0; // deafult to unlimited break; case 'e': program = optarg; break; case 'u': username = optarg; break; case 'p': password = optarg; break; case 'q': queue = amqp_cstring_bytes(optarg); break; case '?': default: print_help(argv[0]); exit(1); } } if ((argc-optind) < 2) { print_help(argv[0]); return 1; } exchange = argv[optind]; bindingkey = argv[optind+1]; if (NULL != program) { // check that the program is executable char *wend; wend = strchr(program, ' '); if(wend){ *wend = '\0'; program_args = wend+1; } if (0 != access(program, X_OK)) { fprintf(stderr, "Program doesn't have execute permission, aborting: %s\n", program); exit(-1); } if(wend){ *wend = ' '; } } if ((passive != 0) && (passive != 1)) { fprintf(stderr, "Queue option 'passive' must be 0 or 1: %u\n", passive); exit(-1); } if ((exclusive != 0) && (exclusive != 1)) { fprintf(stderr, "Queue option 'exclusive' must be 0 or 1: %u\n", exclusive); exit(-1); } if ((durable != 0) && (durable != 1)) { fprintf(stderr, "Queue option 'durable' must be 0 or 1: %u\n", durable); exit(-1); } conn = amqp_new_connection(); die_on_error(sockfd = amqp_open_socket(hostname, port), "Opening socket"); amqp_set_sockfd(conn, sockfd); die_on_amqp_error(amqp_login(conn, vhost, 0, /* channel_max */ 10485760, /* max frame size, 10MB */ 30, /* heartbeat, 30 secs */ AMQP_SASL_METHOD_PLAIN, username, password), "Logging in"); amqp_channel_open(conn, AMQP_CHANNEL); die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel"); { int optval = 1; socklen_t optlen = sizeof(optlen); setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen); } { amqp_queue_declare_ok_t *r = amqp_queue_declare(conn, AMQP_CHANNEL, queue, passive, durable, exclusive, 1, AMQP_EMPTY_TABLE); die_on_amqp_error(amqp_get_rpc_reply(conn), "Declaring queue"); queuename = amqp_bytes_malloc_dup(r->queue); if (queuename.bytes == NULL) { fprintf(stderr, "Out of memory while copying queue name\n"); return 1; } } amqp_queue_bind(conn, AMQP_CHANNEL, queuename, amqp_cstring_bytes(exchange), amqp_cstring_bytes(bindingkey), AMQP_EMPTY_TABLE); die_on_amqp_error(amqp_get_rpc_reply(conn), "Binding queue"); /* Set our prefetch to the maximum number of messages we want to ensure we * don't take more than we want according to --number option from user */ int prefetch_limit = DEFAULT_PREFETCH; if (msg_limit > 0 && msg_limit <= 65535) prefetch_limit = msg_limit; amqp_basic_qos(conn, AMQP_CHANNEL, 0, prefetch_limit, 0); die_on_amqp_error(amqp_get_rpc_reply(conn), "Setting Basic QOS (prefetch limit)"); amqp_basic_consume(conn, AMQP_CHANNEL, queuename, AMQP_EMPTY_BYTES, no_local, no_ack, exclusive, AMQP_EMPTY_TABLE); die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming"); // If executing a program, daemonise if(NULL != program && 0 == foreground_flag) { pid_t pid, sid; pid = fork(); if (pid < 0) { exit(EXIT_FAILURE); } else if(pid > 0) { exit(EXIT_SUCCESS); } umask(0); sid = setsid(); if (sid < 0) exit(EXIT_FAILURE); } { amqp_frame_t frame; int result; int status = 0; /* wait() status, used whether to send ACK */ amqp_basic_deliver_t *d; amqp_basic_properties_t *p; size_t body_target; size_t body_received; install_term_handler(SIGINT); install_term_handler(SIGTERM); install_term_handler(SIGHUP); int msg_count = 0; while (1) { char tempfile[] = "/tmp/amqp.XXXXXX"; int tempfd; // exit if we've reached our maximum message count if((0 != msg_limit) && (msg_limit == msg_count)) break; // we haven't reached our limit; move on to the next msg_count++; if(g_shutdown == 1) break; amqp_maybe_release_buffers(conn); result = amqp_simple_wait_frame(conn, &frame); //printf("Result %d\n", result); if (result < 0) break; //printf("Frame type %d, channel %d\n", frame.frame_type, frame.channel); if (frame.frame_type == AMQP_FRAME_HEARTBEAT) { // send the same heartbeat frame back amqp_send_frame(conn, &frame); continue; } else if (frame.frame_type != AMQP_FRAME_METHOD) continue; //printf("Method %s\n", amqp_method_name(frame.payload.method.id)); if (frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD) continue; d = (amqp_basic_deliver_t *) frame.payload.method.decoded; /* printf("Delivery %u, exchange %.*s routingkey %.*s\n", (unsigned) d->delivery_tag, (int) d->exchange.len, (char *) d->exchange.bytes, (int) d->routing_key.len, (char *) d->routing_key.bytes); */ result = amqp_simple_wait_frame(conn, &frame); if (result < 0) break; if (frame.frame_type != AMQP_FRAME_HEADER) { fprintf(stderr, "Expected header!"); abort(); } p = (amqp_basic_properties_t *) frame.payload.properties.decoded; /* if (p->_flags & AMQP_BASIC_CONTENT_TYPE_FLAG) { printf("Content-type: %.*s\n", (int) p->content_type.len, (char *) p->content_type.bytes); } printf("----\n"); */ body_target = frame.payload.properties.body_size; body_received = 0; tempfd = mkstemp(tempfile); //tempfd = open(tempfile, O_WRONLY | O_CREAT | O_EXCL, 660); while (body_received < body_target) { result = amqp_simple_wait_frame(conn, &frame); if (result < 0) break; if (frame.frame_type != AMQP_FRAME_BODY) { fprintf(stderr, "Expected body!"); abort(); } body_received += frame.payload.body_fragment.len; assert(body_received <= body_target); if (write(tempfd, frame.payload.body_fragment.bytes, frame.payload.body_fragment.len) < 0) { perror("Error while writing received message to temp file"); } } close(tempfd); { char *routekey = (char *)calloc(1, d->routing_key.len + 1); strncpy(routekey, (char *)d->routing_key.bytes, d->routing_key.len); if(NULL != program) { // fork and run the program in the background pid_t pid = fork(); if (pid == 0) { if(execl(program, program, program_args, routekey, tempfile, NULL) == -1) { perror("Could not execute program"); exit(EXIT_FAILURE); } } else { status = 0; wait(&status); } } else { // print to stdout & flush. printf("%s %s\n", routekey, tempfile); fflush(stdout); } free(routekey); } // send ack on successful processing of the frame if((0 == status) && (0 == no_ack)) amqp_basic_ack(conn, frame.channel, d->delivery_tag, 0); if (body_received != body_target) { /* Can only happen when amqp_simple_wait_frame returns <= 0 */ /* We break here to close the connection */ break; } } } die_on_amqp_error(amqp_channel_close(conn, AMQP_CHANNEL, AMQP_REPLY_SUCCESS), "Closing channel"); die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection"); die_on_error(amqp_destroy_connection(conn), "Ending connection"); return 0; }
int main(int argc, const char **argv) { const char *hostname; int port; const char *exchange; const char *routingkey; const char *exchangetype = "direct"; if (argc < 5) { fprintf(stderr, "Usage: receive_logs_direct host port exchange routingkeys...\n"); return 1; } hostname = argv[1]; port = atoi(argv[2]); exchange = argv[3]; int sockfd; int channelid = 1; amqp_connection_state_t conn; conn = amqp_new_connection(); die_on_error(sockfd = amqp_open_socket(hostname, port), "Opening socket"); amqp_set_sockfd(conn, sockfd); die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),"Logging in"); amqp_channel_open(conn, channelid); die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel"); amqp_exchange_declare(conn,channelid,amqp_cstring_bytes(exchange),amqp_cstring_bytes(exchangetype),0,1, amqp_empty_table); die_on_amqp_error(amqp_get_rpc_reply(conn),"Declaring exchange"); amqp_queue_declare_ok_t *r = amqp_queue_declare(conn,channelid,amqp_empty_bytes,0,0,1,0,amqp_empty_table); int i; for(i = 4;i < argc;i++) { routingkey = argv[i]; amqp_queue_bind(conn,channelid,amqp_bytes_malloc_dup(r->queue),amqp_cstring_bytes(exchange), amqp_cstring_bytes(routingkey),amqp_empty_table); } amqp_basic_qos(conn,channelid,0,1,0); amqp_basic_consume(conn,channelid,amqp_bytes_malloc_dup(r->queue),amqp_empty_bytes,0,0,0,amqp_empty_table); die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming"); { amqp_frame_t frame; int result; amqp_basic_deliver_t *d; amqp_basic_properties_t *p; size_t body_target; size_t body_received; while (1) { amqp_maybe_release_buffers(conn); result = amqp_simple_wait_frame(conn, &frame); printf("Result %d\n", result); if (result < 0) break; printf("Frame type %d, channel %d\n", frame.frame_type, frame.channel); if (frame.frame_type != AMQP_FRAME_METHOD) continue; printf("Method %s\n", amqp_method_name(frame.payload.method.id)); if (frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD) continue; d = (amqp_basic_deliver_t *) frame.payload.method.decoded; printf("Delivery %u, exchange %.*s routingkey %.*s\n",(unsigned) d->delivery_tag, (int) d->exchange.len, (char *) d->exchange.bytes, (int) d->routing_key.len, (char *) d->routing_key.bytes); result = amqp_simple_wait_frame(conn, &frame); if (result < 0) break; if (frame.frame_type != AMQP_FRAME_HEADER) { fprintf(stderr, "Expected header!"); abort(); } p = (amqp_basic_properties_t *) frame.payload.properties.decoded; if (p->_flags & AMQP_BASIC_CONTENT_TYPE_FLAG) { printf("Content-type: %.*s\n", (int) p->content_type.len, (char *) p->content_type.bytes); } body_target = frame.payload.properties.body_size; body_received = 0; int sleep_seconds = 0; while (body_received < body_target) { result = amqp_simple_wait_frame(conn, &frame); if (result < 0) break; if (frame.frame_type != AMQP_FRAME_BODY) { fprintf(stderr, "Expected body!"); abort(); } body_received += frame.payload.body_fragment.len; assert(body_received <= body_target); int i; for(i = 0; i<frame.payload.body_fragment.len; i++) { printf("%c",*((char*)frame.payload.body_fragment.bytes+i)); if(*((char*)frame.payload.body_fragment.bytes+i) == '.') sleep_seconds++; } printf("\n"); } if (body_received != body_target) { /* Can only happen when amqp_simple_wait_frame returns <= 0 */ /* We break here to close the connection */ break; } /* do something */ sleep(sleep_seconds); amqp_basic_ack(conn,channelid,d->delivery_tag,0); } } die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel"); die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection"); die_on_error(amqp_destroy_connection(conn), "Ending connection"); return 0; }
int main(int argc,const char *argv[]) { const char *hostName; int port; const char *queueName; int prefetchCount; int noAck = 1; if (argc < 6) { fprintf(stderr,"Usage: consumer host port queuename prefetch_count no_ack\n"); exit(1); } hostName = argv[1]; port = atoi(argv[2]); queueName = argv[3]; prefetchCount = atoi(argv[4]); if(strcmp(argv[5],"false")==0) noAck = 0; int sockfd; int channelId = 1; amqp_connection_state_t conn; conn = amqp_new_connection(); die_on_error(sockfd = amqp_open_socket(hostName, port), "Opening socket"); amqp_set_sockfd(conn, sockfd); die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),"Logging in"); amqp_channel_open(conn, channelId); die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel"); amqp_basic_qos(conn,channelId,0,prefetchCount,0); amqp_basic_consume(conn,channelId,amqp_cstring_bytes(queueName),amqp_empty_bytes,0,noAck,0,amqp_empty_table); die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming"); int count = 0; amqp_frame_t frame; int result; amqp_basic_deliver_t *d; amqp_basic_properties_t *p; size_t body_target; size_t body_received; long long start = timeInMilliseconds(); while(1){ { amqp_maybe_release_buffers(conn); result = amqp_simple_wait_frame(conn, &frame); if (result < 0) break; if (frame.frame_type != AMQP_FRAME_METHOD) continue; if (frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD) continue; d = (amqp_basic_deliver_t *) frame.payload.method.decoded; result = amqp_simple_wait_frame(conn, &frame); if (result < 0) break; if (frame.frame_type != AMQP_FRAME_HEADER) { fprintf(stderr, "Expected header!"); abort(); } p = (amqp_basic_properties_t *) frame.payload.properties.decoded; body_target = frame.payload.properties.body_size; body_received = 0; while (body_received < body_target) { result = amqp_simple_wait_frame(conn, &frame); if (result < 0) break; if (frame.frame_type != AMQP_FRAME_BODY) { fprintf(stderr, "Expected body!"); abort(); } body_received += frame.payload.body_fragment.len; assert(body_received <= body_target); } if (body_received != body_target) { break; } if(!noAck) amqp_basic_ack(conn,channelId,d->delivery_tag,0); } count++; if(count%10000 == 0) { long long end = timeInMilliseconds(); fprintf(stderr,"round %d takes %lld millseconds(10000 messages consumed every round)\n",count/10000-1,end-start); start = timeInMilliseconds(); } } die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel"); die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection"); die_on_error(amqp_destroy_connection(conn), "Ending connection"); return 0; }