A Preliminary Study of rabbitmq-c

Source: Internet
Author: User
Tags amq

RabbitMQ is really a good thing. Of course, it also supports C-language client development. There are few examples and documents, so you can only view example in the project to understand them, and simply sort them out to avoid detours. The main reason is that the corresponding version is not as good as Maven. Only the class libraries and examples can be well implemented. Next, let's take a look at what we need.

Environment: Ubuntu 13.04

Rabbitmq-server default 3.0.2-1

Librabbitmq-dev default 0.0.1.hg216-1

Qmake for project construction (which is much simpler)

1 consumer

1.1 consumer. pro content
SOURCES = utils. cpp amqp_consumer.cpp platform_utils.cpp

HEADERS = utils. h

VPATH + =/usr/include

CONFIG + = release

TARGET = consumer

LIBS + =-lrabbitmq

1.2 amqp_consumer.cpp code
The code here comes from the rabbitmq-c-v0.3.0. (Some special macro references have been adjusted)

# Include <stdlib. h>

# Include <stdio. h>

# Include <string. h>

# Include <stdint. h>

# Include <amqp. h>

# Include <amqp_framing.h>

# Include <assert. h>

# Include "utils. h"

# Define SUMMARY_EVERY_US 1000000

 


Static void run (amqp_connection_state_t conn)

{

Uint64_t start_time = now_microseconds ();

Int received = 0;

Int previus_received = 0;

Uint64_t previus_report_time = start_time;

Uint64_t next_summary_time = start_time + SUMMARY_EVERY_US;

Amqp_frame_t frame;

Int result;

Size_t body_inclued;

Size_t body_target;

Uint64_t now;

 


While (1 ){

Now = now_microseconds ();

If (now> next_summary_time ){

Int countOverInterval = received-previus_received;

Double intervalRate = countOverInterval/(now-previus_report_time)/1000000.0 );

Printf ("% d ms: Received % d-% d since last report (% d Hz) \ n ",

(Int) (now-start_time)/1000, received, countOverInterval, (int) intervalRate );

Previus_received = received;

Previous_report_time = now;

Next_summary_time + = SUMMARY_EVERY_US;

}

Amqp_maybe_release_buffers (conn );

Result = amqp_simple_wait_frame (conn, & frame );

If (result <0)

Return;

If (frame. frame_type! = AMQP_FRAME_METHOD)

Continue;

If (frame. payload. method. id! = AMQP_BASIC_DELIVER_METHOD)

Continue;

 


Result = amqp_simple_wait_frame (conn, & frame );

If (result <0)

Return;

If (frame. frame_type! = AMQP_FRAME_HEADER ){

Fprintf (stderr, "Expected header! ");

Abort ();

}

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)

Return;

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 );

}

Received ++;

}

}

 


Int main (int argc, char const * argv ){

Char const * hostname;

Int port;

Char const * exchange;

Char const * bindingkey;

Int sockfd;

Amqp_connection_state_t conn;

Amqp_bytes_t queuename;

 


If (argc <3 ){

Fprintf (stderr, "Usage: amqp_consumer host port \ n ");

Return 1;

}

Hostname = argv [1];

Port = atoi (argv [2]);

Exchange = "amq. direct";/* argv [3]; */

Bindingkey = "test queue";/* argv [4]; */

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, 1 );

Die_on_amqp_error (amqp_get_rpc_reply (conn), "Opening channel ");

{

Amqp_queue_declare_ OK _t * r = amqp_queue_declare (conn, 1, AMQP_EMPTY_BYTES/* amqp_empty_bytes */, 0, 0, 1,

AMQP_EMPTY_TABLE/* 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 ");

Return 1;

}

}

Amqp_queue_bind (conn, 1, queuename, amqp_cstring_bytes (exchange), amqp_cstring_bytes (bindingkey ),

AMQP_EMPTY_TABLE/* amqp_empty_table */);

Die_on_amqp_error (amqp_get_rpc_reply (conn), "Binding queue ");

Amqp_basic_consume (conn, 1, queuename, AMQP_EMPTY_BYTES/* amqp_empty_bytes */, 0, 1, 0, AMQP_EMPTY_TABLE/* amqp_empty_table */);

Die_on_amqp_error (amqp_get_rpc_reply (conn), "Consuming ");

Run (conn );

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;

}


2 producer
2.1 producer. pro content
SOURCES = utils. cpp amqp_producer.cpp platform_utils.cpp
HEADERS = utils. h
VPATH + =/usr/include
CONFIG + = release
TARGET = producer
LIBS + =-lrabbitmq
2.2 amqp_producer.cpp code
The code here comes from the rabbitmq-c-v0.3.0. (Some special macro references have been adjusted)

# Include <stdlib. h>

# Include <stdio. h>

# Include <string. h>

# Include <stdint. h>

# Include <amqp. h>

# Include <amqp_framing.h>

# Include "utils. h"

# Define SUMMARY_EVERY_US 1000000

 


Static void send_batch (amqp_connection_state_t conn,

Char const * queue_name,

Int rate_limit,

Int message_count)

{

Uint64_t start_time = now_microseconds ();

Int I;

Int sent = 0;

Int previous_sent = 0;

Uint64_t previus_report_time = start_time;

Uint64_t next_summary_time = start_time + SUMMARY_EVERY_US;

Char message [256];

Amqp_bytes_t message_bytes;

 


For (I = 0; I <(int) sizeof (message); I ++ ){

Message [I] = I & 0xff;

}

Message_bytes.len = sizeof (message );

Message_bytes.bytes = message;

For (I = 0; I <message_count; I ++ ){

Uint64_t now = now_microseconds ();

Die_on_error (amqp_basic_publish (conn, 1, amqp_cstring_bytes ("amq. direct"), amqp_cstring_bytes (queue_name ),

0, 0, NULL, message_bytes), "Publishing ");

Sent ++;

If (now> next_summary_time ){

Int countOverInterval = sent-previus_sent;

Double intervalRate = countOverInterval/(now-previus_report_time)/1000000.0 );

Printf ("% d ms: Sent % d-% d since last report (% d Hz) \ n", (int) (now-start_time)/1000, sent,

CountOverInterval, (int) intervalRate );

Previus_sent = sent;

Previous_report_time = now;

Next_summary_time + = SUMMARY_EVERY_US;

}

While (I * 1000000.0)/(now-start_time)> rate_limit ){

Microsleep (2000 );

Now = now_microseconds ();

}

}

{

Uint64_t stop_time = now_microseconds ();

Int total_delta = stop_time-start_time;

Printf ("PRODUCER-Message count: % d \ n", message_count );

Printf ("Total time, milliseconds: % d \ n", total_delta/1000 );

Printf ("Overall messages-per-second: % g \ n", (message_count/(total_delta/1000000.0 )));

}

}

 


Int main (int argc, char const * argv ){

Char const * hostname;

Int port;

Int rate_limit;

Int message_count;

Int sockfd;

Amqp_connection_state_t conn;

If (argc <5 ){

Fprintf (stderr, "Usage: amqp_producer host port rate_limit message_count \ n ");

Return 1;

}

Hostname = argv [1];

Port = atoi (argv [2]);

Rate_limit = atoi (argv [3]);

Message_count = atoi (argv [4]);

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, 1 );

Die_on_amqp_error (amqp_get_rpc_reply (conn), "Opening channel ");

Send_batch (conn, "test queue", rate_limit, message_count );

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;

}

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.