CopernicaMarketingSoftware / AMQP-CPP

C++ library for asynchronous non-blocking communication with RabbitMQ
Apache License 2.0
864 stars 334 forks source link

LibUV Implementation/Example is broken #491

Open ksmit799 opened 1 year ago

ksmit799 commented 1 year ago

Describe the bug Using the LibUvHandler included in the source produces compiler errors when using the latest version of LibUV (1.44.2). From what I can see, it hasn't been updated since 2016 whereas LibEV seems to be more up-to-date. I can have a go at fixing this myself, but my C libuv knowledge is very limited (we're using a C++ abstraction layer in our project.)

Expected behavior and actual behavior Should be able to compile using the example code provided. Instead produces the following errors: error C2664: 'int uv_fileno(const uv_handle_t *,uv_os_fd_t *)': cannot convert argument 2 from 'int *' to 'uv_os_fd_t *'

After fixing by re-interpret casting:

int fd = -1;
uv_fileno(reinterpret_cast<uv_handle_t*>(handle),
          reinterpret_cast<uv_os_fd_t *>(&fd));

The following linking error occurs: error LNK2019: unresolved external symbol "public: void __cdecl AMQP::TcpConnection::process(int,int)"

Sample code See examples/libuv.cpp

SamuelRobotiq commented 1 year ago

@ksmit799 have you found a workaround?

ksmit799 commented 1 year ago

@ksmit799 have you found a workaround?

Yes, I created a new class that inherited from public AMQP::ConnectionHandler and manually created a TCP connection via libuv.

It's then pretty trivial to follow the docs for connection handler and send/receive data. The LibUvHandler has a dependency on tcp_linux which isn't designed to be cross platform, so that might explain the linker errors (I'm on Windows atm)

EmielBruijntjes commented 1 year ago

The LibUvHandler was not written by me, but by @ogapo. Maybe he feels like fixing or improving it? Otherwise someone else has to jump in and send in a pull request. My time is constrained and I have never worked with libuv before so please do not expect a fix from my hand in the foreseeable future.

Note that the libuv handler has less features than for example the libev handler. For example, there is no support for heartbeats.

ksmit799 commented 1 year ago

@EmielBruijntjes Is there a specific reason why the LibUV (or LibEV for that matter) handlers are wrapped around the TCPHandler? It requires OpenSSL to compile and imports from tcp_linux. I'd be happy to contribute a working version of my setup implementing AMQP::ConnectionHandler that's platform agnostic.

EmielBruijntjes commented 1 year ago

Mainly for practical reasons: that seemed easier. But conceptually you can indeed implement your own handler directly on top of AMQP::ConnectionHandler.

gunhak01 commented 1 year ago

@ksmit799 I'm a newbie in this area. I tried to create a class that inherits from the connectionhandler in the way you described and do the tcp connection manually, but I'm not sure how to apply it to a TcpConnection with the handler I have. Could you explain it in more detail? Thanks

ksmit799 commented 1 year ago

@ksmit799 I'm a newbie in this area. I tried to create a class that inherits from the connectionhandler in the way you described and do the tcp connection manually, but I'm not sure how to apply it to a TcpConnection with the handler I have. Could you explain it in more detail? Thanks

You can have a look at our implementation here: https://github.com/ksmit799/Ardos/blob/main/src/messagedirector/message_director.cpp

NB: We're using uvw to simplify using libuv within C++. There's some application specific code in that file but you should be able to get the gist of things.