Próbuję napisać klienta AMQP 1.0 przy użyciu Qpid Proton w C. Nie chcę używać komunikatora. Chcę użyć silnika proton-c. Mam problem z ustaleniem, jak to zrobić. Moim głównym punktem przyklejania jest ustawienie punktu końcowego dla połączenia. Jedyny przykład klienta C używającego silnika proton-c, jaki mogę znaleźć, jest tutaj.Klient Qpid Proton korzystający z interfejsu API silnika nie wysyłając wiadomości do serwera
https://github.com/apache/qpid-proton/blob/master/examples/engine/c/psend.c
jednak używa konstrukcjom, które nie są częścią Qpid protonowej C API 0.12.0. W szczególności nie widzę pn_driver_t ani pn_connector_t jako części interfejsu API 0.12.0.
Próbuję wykonać ogólny przepływ pracy zdefiniowany w specyfikacji AMQP 1.0 1) utworzyć połączenie, 2) utworzyć sesję, 3) utworzyć łącze nadawcy. Nie mam dużego doświadczenia z C i jest to mój pierwszy raz, kiedy korzystam z nie-posłańców z biblioteki Qpid Proton, więc wybacz mi, jeśli przegapię coś oczywistego. Oto mój obecny kod. Próbowałem różnych opcji i szukałem dni.
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "proton/message.h"
#include "proton/messenger.h"
#include "proton/connection.h"
#include "proton/session.h"
#include "proton/link.h"
#include "proton/delivery.h"
#include "proton/event.h"
#include "proton/engine.h"
//State integer values are defined in Connection macros
//https://qpid.apache.org/releases/qpid-proton-0.12.0/proton/c/api/group__connection.html
void print_state(char * name, pn_state_t state)
{
printf("[%s] local: %i, remote: %i\n", name, PN_LOCAL_MASK & state, PN_REMOTE_MASK & state);
}
//Reference https://github.com/apache/qpid-proton/blob/master/examples/engine/c/psend.c
void send_engine()
{
struct pn_connection_t * connection;
connection = pn_connection();
//STACKOVERFLOW - I have a feeling this is not right, but cannot find an alternative to set protocol (amqp or ws) the hostname and port. I see a way to set the hostname only
pn_connection_set_container(connection, "amqp://amqpserver:port");
print_state("Connection Initialized", pn_connection_state(connection));
pn_transport_t * transport;
transport = pn_transport();
int r = pn_transport_bind(transport, connection);
if (r != 0)
{
printf("transport bind error: %i\n", r);
}
pn_connection_open(connection);
print_state("Connection Opened", pn_connection_state(connection));
pn_session_t * sess;
sess = pn_session(connection);
print_state("Session Initialized", pn_session_state(sess));
pn_session_open(sess);
print_state("Session Opened", pn_session_state(sess));
pn_link_t * sender;
sender = pn_sender(sess, "c-client");
//the queue name in "toserver"
pn_terminus_set_address(pn_link_target(sender), "toserver");
print_state("Sender Link Initialized", pn_link_state(sender));
pn_link_open(sender);
print_state("Sender Link Opened", pn_link_state(sender));
pn_delivery_t *delivery;
char *tagID = "uid";
delivery = pn_delivery(sender, pn_dtag(tagID, strlen(tagID)));
char *msg = "abc";
printf("%zd\n", pn_link_send(sender, msg, strlen(msg)));
pn_delivery_settle(delivery);
printf("Delivery stettled %d\n", pn_delivery_settled(delivery));
print_state("Connection End", pn_connection_state(connection));
print_state("Session End", pn_session_state(sess));
print_state("Sender Link End", pn_link_state(sender));
//TODO free everything
}
int main (int argc, char *argv[])
{
send_engine();
printf("done\n");
return 0;
}
Na moim serwerze AMQP włączam śledzenie poziomu ramki i nie widzę żadnej komunikacji od klienta. To nie jest problem z serwerem. Współpracuje z wieloma innymi klientami, w tym z klientem C korzystającym z interfejsu API komunikatora. Czego mi brakuje w tej próbce? Dziękuję Ci!
Uwaga: starałem się rozwiązać to w sposób wyczerpujący i podałem jak najwięcej kontekstu.