Search code examples
socketstcpasyncsocketlibuv

Libuv - multiple TCP requests on a single connection


Using Libuv, I have implemented a TCP Server A that calls another TCP Server B.

As Server A keeps getting requests, I send requests to Server B using a single TCP connection established from A to B.

Given that Libuv is async and callback oriented, how do I differentiate between the responses that I get Server B? i.e. how do I send the correct result back to the client of Server A?

The docs say that the uv_read_cb callback will be called several times. How do I know for which original request the uv_read_cb is being called for?


Solution

  • TCP is stream-based, not message-based - you're not sending individual messages, you're sending an undiferentiated stream of data. So in short, what you're trying to do is always going to be tricky, and the handling is entirely up to you.

    You need to create your own protocol on top of TCP. Depending on your requirements, this could be as simple as assigning a unique ID and sending it with the response. Of course, you'll also have to handle the message translation itself - as with any TCP-based message protocol. I'd strongly suggest only ever using a single thread to write any data to a TCP stream - you can use a thread-safe queue to post the messages so that they aren't broken by the usual asynchronous writes.

    The read callback will pick up fragmented and coalesced messages, no doubt about it. It's a standard TCP scenario, and you need to be prepared for it. That's why I'd also recommend a single reader, which will read from the stream, and post every parsed message to another queue. You can use the unique ID you sent with the request to pair it up as needed.