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); } }
int lc_bus_publish_unicast(const char *buf, int buf_len, uint32_t queue_id) { amqp_connection_state_t *conn = NULL; amqp_bytes_t body = { len: buf_len, bytes: (void *)buf }; amqp_basic_properties_t props; int res = 0; if (!buf || queue_id >= NUM_LC_BUS_QUEUE) { return LC_BUS_ERR; } conn = lc_bus_get_connection(); if (!conn) { return LC_BUS_ERR; } memset(&props, 0, sizeof props); props._flags = AMQP_BASIC_DELIVERY_MODE_FLAG; props.delivery_mode = 2; /* persistent delivery mode */ res = amqp_basic_publish( *conn, LC_BUS_CHANNEL, amqp_cstring_bytes(lc_bus_exchange[LC_BUS_EXCHANGE_DIRECT][0]), amqp_cstring_bytes(lc_bus_queue[queue_id]), 0, /* mandatory */ 0, /* immediate */ &props, body ); if (res) { LB_SYSLOG(LOG_ERR, "failed channel=%u queue=%u ret=%d\n", LC_BUS_CHANNEL, queue_id, res); return LC_BUS_ERR; } else { LB_SYSLOG(LOG_INFO, "succeed channel=%u queue=%u\n", LC_BUS_CHANNEL, queue_id); } return LC_BUS_OK; } int lc_bus_publish_broadcast(const char *buf, int buf_len) { /* TODO */ return LC_BUS_OK; } int lc_bus_publish_multicast(const char *buf, int buf_len) { /* TODO */ return LC_BUS_OK; } static int consumer_queueids[NUM_LC_BUS_QUEUE]; static int lc_bus_init_consumer_atomic(amqp_connection_state_t *conn, uint32_t flag, uint32_t queue_id) { amqp_basic_consume_ok_t *res_consume = NULL; amqp_rpc_reply_t ret; if (queue_id >= NUM_LC_BUS_QUEUE) { return LC_BUS_ERR; } #if 0 amqp_basic_qos_ok_t *res_qos = NULL; if (count > 0 && count <= 65535 && !(res_qos = amqp_basic_qos( *conn, 1, 0, count, 0 ))) { die_rpc(amqp_get_rpc_reply(*conn), "basic.qos"); return LC_BUS_ERR; } #endif res_consume = amqp_basic_consume( *conn, LC_BUS_CHANNEL, amqp_cstring_bytes(lc_bus_queue[queue_id]), amqp_empty_bytes, /* consumer_tag */ 0, /* no_local */ (flag & LC_BUS_CONSUME_WITH_ACK) ? 0 : 1, /* no_ack */ 0, /* exclusive */ amqp_empty_table /* arguments */ ); if (!res_consume) { ret = amqp_get_rpc_reply(*conn); if (ret.reply_type != AMQP_RESPONSE_NORMAL) { LB_SYSLOG(LOG_ERR, "[%s] failed, channel=%u %s\n", lc_bus_queue[queue_id], LC_BUS_CHANNEL, amqp_rpc_reply_string(&ret)); return LC_BUS_ERR; } } consumer_queueids[queue_id] = 1; LB_SYSLOG(LOG_INFO, "[%s] succeed channel=%u.\n", lc_bus_queue[queue_id], LC_BUS_CHANNEL); return LC_BUS_OK; }
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, 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 *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; }