A server that can be used to demonstrate direct (no broker) peer-to-peer communication It can accept an incoming connection from either the send.c or receive.c examples and will act as the directly-connected counterpart (receive or send)
#include <stdio.h>
#include <stdlib.h>
typedef struct app_data_t {
const char *host, *port;
const char *amqp_address;
const char *container_id;
int message_count;
int sent;
int acknowledged;
int received;
} app_data_t;
static const int BATCH = 1000;
static int exit_code = 0;
}
exit_code = 1;
}
}
static void send_message(app_data_t *app,
pn_link_t *sender) {
exit_code = 1;
}
}
if (!err) {
pn_string_t *s = pn_string(NULL);
printf("%s\n", pn_string_get(s));
fflush(stdout);
pn_free(s);
free(data.start);
} else {
exit_code = 1;
}
}
static void handle_receive(app_data_t *app,
pn_event_t* event) {
pn_link_flow(l, app->message_count ? app->message_count : BATCH);
} break;
ssize_t recv;
m->size += size;
m->start = (char*)realloc(m->start, m->size);
printf("Message aborted\n");
fflush(stdout);
m->size = 0;
}
else if (recv < 0 && recv !=
PN_EOS) {
decode_message(*m);
*m = pn_rwbytes_null;
if (app->message_count == 0) {
}
} else if (++app->received >= app->message_count) {
printf("%d messages received\n", app->received);
}
}
}
break;
}
default:
break;
}
}
static void handle_send(app_data_t* app,
pn_event_t* event) {
} break;
while (
pn_link_credit(sender) > 0 && app->sent < app->message_count) {
++app->sent;
send_message(app, sender);
}
break;
}
if (++app->acknowledged == app->message_count) {
printf("%d messages sent and acknowledged\n", app->acknowledged);
}
}
} break;
default:
break;
}
}
static bool handle(app_data_t* app,
pn_event_t* event) {
char port[256];
printf("listening on %s\n", port);
fflush(stdout);
break;
}
break;
break;
break;
}
break;
}
break;
}
break;
break;
break;
break;
break;
app->listener = NULL;
break;
return false;
break;
default: {
if (l) {
handle_send(app, event);
} else {
handle_receive(app, event);
}
}
}
}
return exit_code == 0;
}
void run(app_data_t *app) {
do {
if (!handle(app, e)) {
return;
}
}
} while(true);
}
int main(int argc, char **argv) {
struct app_data_t app = {0};
app.container_id = argv[0];
app.host = (argc > 1) ? argv[1] : "";
app.port = (argc > 2) ? argv[2] : "amqp";
app.amqp_address = (argc > 3) ? argv[3] : "examples";
app.message_count = (argc > 4) ? atoi(argv[4]) : 10;
run(&app);
free(app.msgout.start);
free(app.msgin.start);
return exit_code;
}
A connection to a remote AMQP peer.
@ PN_ULONG
The ulong AMQP type.
Definition: codec.h:96
pn_bytes_t pn_bytes(size_t size, const char *start)
Create a pn_bytes_t.
A discriminated union that holds any scalar AMQP value.
Definition: codec.h:200
A non-const byte buffer.
Definition: types.h:235
const char * pn_condition_get_name(pn_condition_t *condition)
Returns the name associated with the exceptional condition, or NULL if there is no conditional inform...
bool pn_condition_is_set(pn_condition_t *condition)
Returns true if the condition object is holding some information, i.e.
struct pn_condition_t pn_condition_t
An AMQP Condition object.
Definition: condition.h:64
int pn_condition_format(pn_condition_t *, const char *name, const char *fmt,...)
Set the name and printf-style formatted description.
const char * pn_condition_get_description(pn_condition_t *condition)
Gets the description associated with the exceptional condition.
void pn_connection_open(pn_connection_t *connection)
Open a connection.
pn_condition_t * pn_connection_remote_condition(pn_connection_t *connection)
Get the remote condition associated with the connection endpoint.
struct pn_connection_t pn_connection_t
An AMQP Connection object.
Definition: types.h:285
void pn_connection_close(pn_connection_t *connection)
Close a connection.
void pn_connection_set_container(pn_connection_t *connection, const char *container)
Set the AMQP Container name advertised by a connection object.
bool pn_data_enter(pn_data_t *data)
Sets the parent node to the current node and clears the current node.
int pn_data_put_map(pn_data_t *data)
Puts an empty map value into a pn_data_t.
struct pn_data_t pn_data_t
An AMQP Data object.
Definition: codec.h:375
int pn_data_put_string(pn_data_t *data, pn_bytes_t string)
Puts a PN_STRING value.
bool pn_data_exit(pn_data_t *data)
Sets the current node to the parent node and the parent node to its own parent.
int pn_data_put_int(pn_data_t *data, int32_t i)
Puts a PN_INT value.
bool pn_delivery_readable(pn_delivery_t *delivery)
Check if a delivery is readable.
size_t pn_delivery_pending(pn_delivery_t *delivery)
Get the amount of pending message data for a delivery.
bool pn_delivery_partial(pn_delivery_t *delivery)
Check if a delivery only has partial message data.
void pn_delivery_update(pn_delivery_t *delivery, uint64_t state)
Update the disposition of a delivery.
pn_delivery_t * pn_delivery(pn_link_t *link, pn_delivery_tag_t tag)
Create a delivery on a link.
void pn_delivery_settle(pn_delivery_t *delivery)
Settle a delivery.
uint64_t pn_delivery_remote_state(pn_delivery_t *delivery)
Get the remote disposition state for a delivery.
#define PN_ACCEPTED
The PN_ACCEPTED delivery state is a terminal state indicating that the delivery was successfully proc...
Definition: disposition.h:66
struct pn_delivery_t pn_delivery_t
An AMQP Delivery object.
Definition: types.h:405
pn_link_t * pn_delivery_link(pn_delivery_t *delivery)
Get the parent link for a delivery object.
pn_delivery_tag_t pn_dtag(const char *bytes, size_t size)
Construct a delivery tag.
const char * pn_error_text(pn_error_t *error)
Get the error text.
#define PN_ABORTED
Delivery aborted error.
Definition: error.h:57
#define PN_EOS
End of stream.
Definition: error.h:47
const char * pn_code(int code)
Get the name of the error code.
pn_delivery_t * pn_event_delivery(pn_event_t *event)
Get the delivery associated with an event.
pn_transport_t * pn_event_transport(pn_event_t *event)
Get the transport associated with an event.
const char * pn_event_type_name(pn_event_type_t type)
Get a human readable name for an event type.
pn_connection_t * pn_event_connection(pn_event_t *event)
Get the connection associated with an event.
pn_link_t * pn_event_link(pn_event_t *event)
Get the link associated with an event.
struct pn_event_t pn_event_t
Notification of a state change in the protocol engine.
Definition: event.h:75
pn_event_type_t pn_event_type(pn_event_t *event)
Get the type of an event.
pn_session_t * pn_event_session(pn_event_t *event)
Get the session associated with an event.
@ PN_LISTENER_ACCEPT
Indicates the listener has an incoming connection, call pn_listener_accept2() to accept it.
Definition: event.h:316
@ PN_LINK_REMOTE_CLOSE
The remote endpoint has closed the link.
Definition: event.h:223
@ PN_CONNECTION_REMOTE_CLOSE
The remote endpoint has closed the connection.
Definition: event.h:149
@ PN_CONNECTION_INIT
The connection has been created.
Definition: event.h:113
@ PN_TRANSPORT_CLOSED
Indicates that the both the head and tail of the transport are closed.
Definition: event.h:295
@ PN_SESSION_REMOTE_CLOSE
The remote endpoint has closed the session.
Definition: event.h:186
@ PN_LINK_REMOTE_OPEN
The remote endpoint has opened the link.
Definition: event.h:211
@ PN_PROACTOR_TIMEOUT
Timeout set by pn_proactor_set_timeout() time limit expired.
Definition: event.h:334
@ PN_LINK_FLOW
The flow control state for a link has changed.
Definition: event.h:241
@ PN_LINK_REMOTE_DETACH
The remote endpoint has detached the link.
Definition: event.h:235
@ PN_LISTENER_OPEN
The listener is listening.
Definition: event.h:350
@ PN_DELIVERY
A delivery has been created or updated.
Definition: event.h:254
@ PN_PROACTOR_INACTIVE
The proactor has become inactive: all listeners and connections were closed and the timeout (if set) ...
Definition: event.h:344
@ PN_CONNECTION_REMOTE_OPEN
The remote endpoint has opened the connection.
Definition: event.h:137
@ PN_LISTENER_CLOSE
Indicates the listener has closed.
Definition: event.h:322
@ PN_CONNECTION_BOUND
The connection has been bound to a transport.
Definition: event.h:119
@ PN_SESSION_REMOTE_OPEN
The remote endpoint has opened the session.
Definition: event.h:174
ssize_t pn_link_recv(pn_link_t *receiver, char *bytes, size_t n)
Receive message data for the current delivery on a link.
void pn_link_close(pn_link_t *link)
Close a link.
pn_condition_t * pn_link_condition(pn_link_t *link)
Get the local condition associated with a link endpoint.
int pn_link_credit(pn_link_t *link)
Get the credit balance for a link.
bool pn_link_is_sender(pn_link_t *link)
Test if a link is a sender.
struct pn_link_t pn_link_t
An AMQP Link object.
Definition: types.h:315
pn_condition_t * pn_link_remote_condition(pn_link_t *link)
Get the remote condition associated with a link endpoint.
pn_terminus_t * pn_link_target(pn_link_t *link)
Access the locally defined target definition for a link.
void pn_link_open(pn_link_t *link)
Open a link.
pn_session_t * pn_link_session(pn_link_t *link)
Get the parent session for a link object.
void pn_link_free(pn_link_t *link)
Free a link object.
void pn_link_flow(pn_link_t *receiver, int credit)
Grant credit for incoming deliveries on a receiver.
PNP_EXTERN void pn_listener_close(pn_listener_t *l)
Close the listener.
PNP_EXTERN void pn_listener_accept2(pn_listener_t *listener, pn_connection_t *connection, pn_transport_t *transport)
Accept an incoming connection request using transport and connection, which can be configured before ...
PNP_EXTERN pn_listener_t * pn_event_listener(pn_event_t *event)
Return the listener associated with an event.
struct pn_listener_t pn_listener_t
A listener for incoming connections.
Definition: types.h:424
PNP_EXTERN pn_condition_t * pn_listener_condition(pn_listener_t *l)
Get the error condition for a listener.
PNP_EXTERN pn_listener_t * pn_listener(void)
Create a listener to pass to pn_proactor_listen()
int pn_message_set_id(pn_message_t *msg, pn_msgid_t id)
Set the id for a message.
pn_data_t * pn_message_body(pn_message_t *msg)
Get and set the body of a message.
void pn_message_free(pn_message_t *msg)
Free a previously constructed pn_message_t.
ssize_t pn_message_send(pn_message_t *msg, pn_link_t *sender, pn_rwbytes_t *buf)
Unsettled API
pn_error_t * pn_message_error(pn_message_t *msg)
Access the error information for a message.
pn_message_t * pn_message(void)
Construct a new pn_message_t.
int pn_message_decode(pn_message_t *msg, const char *bytes, size_t size)
Decode/load message content from AMQP formatted binary data.
struct pn_message_t pn_message_t
An AMQP Message object.
Definition: message.h:51
PNP_EXTERN void pn_connection_wake(pn_connection_t *connection)
Return a PN_CONNECTION_WAKE event for connection as soon as possible.
#define PN_MAX_ADDR
Size of buffer that can hold the largest connection or listening address.
Definition: proactor.h:74
PNP_EXTERN pn_event_batch_t * pn_proactor_wait(pn_proactor_t *proactor)
Wait until there are Proactor events to handle.
PNP_EXTERN void pn_proactor_free(pn_proactor_t *proactor)
Free the proactor.
struct pn_event_batch_t pn_event_batch_t
A batch of events that must be handled in sequence.
Definition: types.h:462
PNP_EXTERN pn_event_t * pn_event_batch_next(pn_event_batch_t *batch)
Remove the next event from the batch and return it.
PNP_EXTERN int pn_netaddr_host_port(const pn_netaddr_t *na, char *host, size_t hlen, char *port, size_t plen)
Get the host and port name from na as separate strings.
struct pn_proactor_t pn_proactor_t
A harness for multithreaded IO.
Definition: types.h:442
PNP_EXTERN pn_proactor_t * pn_proactor(void)
Create a proactor.
PNP_EXTERN void pn_proactor_listen(pn_proactor_t *proactor, pn_listener_t *listener, const char *addr, int backlog)
Start listening for incoming connections.
PNP_EXTERN const pn_netaddr_t * pn_listener_addr(pn_listener_t *l)
Get the listening addresses of a listener.
PNP_EXTERN void pn_proactor_done(pn_proactor_t *proactor, pn_event_batch_t *events)
Call when finished handling a batch of events.
PNP_EXTERN int pn_proactor_addr(char *addr, size_t size, const char *host, const char *port)
Format a host:port address string for pn_proactor_connect() or pn_proactor_listen()
void pn_sasl_allowed_mechs(pn_sasl_t *sasl, const char *mechs)
SASL mechanisms that are to be considered for authentication.
pn_sasl_t * pn_sasl(pn_transport_t *transport)
Construct an Authentication and Security Layer object.
void pn_session_free(pn_session_t *session)
Free a session object.
void pn_session_close(pn_session_t *session)
Close a session.
void pn_session_open(pn_session_t *session)
Open a session.
pn_connection_t * pn_session_connection(pn_session_t *session)
Get the parent connection for a session object.
pn_condition_t * pn_session_remote_condition(pn_session_t *session)
Get the remote condition associated with the session endpoint.
int pn_terminus_set_address(pn_terminus_t *terminus, const char *address)
Set the address of a terminus object.
void pn_transport_require_auth(pn_transport_t *transport, bool required)
Set whether a non-authenticated transport connection is allowed.
struct pn_transport_t pn_transport_t
A network channel supporting an AMQP connection.
Definition: types.h:435
pn_condition_t * pn_transport_condition(pn_transport_t *transport)
Get additional information about the condition of the transport.
A channel for transferring messages.
Unsettled API - A listener for incoming connections.
A mutable holder of application content.
Unsettled API - The network address of a proactor transport.
Unsettled API - An API for multithreaded IO.
SASL secure transport layer.
A network channel supporting an AMQP connection.