CopernicaMarketingSoftware/AMQP-CPP

LibUV Implementation/Example is broken

Opened this issue ยท 8 comments

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

@ksmit799 have you found a workaround?

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

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.

@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.

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

@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 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.

I've been trying for a day or two to replicate what's Ardos with uvw without success.

I don't know if I'm missing something somewhere, but the loop just never starts. It's just directly dead (checked with gdb) and not a single event seems to be triggered or enqueued.

Even after reading a bunch of uv's docs and juggling between Ardos' example and the docs for this lib, I still feel quite lost. ๐Ÿ˜–

Here's a repo

Edit: I managed to make it work yay !