Node.js flush socket after write

12,930

Solution 1

I refer to the socket.write(data, [encoding], [callback]) API:

The optional callback parameter will be executed when the data is finally written out - this may not be immediately.

So, set up a queue (array is fine) which holds messages to be sent.
When the above callback is being called, check the queue and send if needed..

This however does not guarantee what you're looking for, you'll have to test. Unfortunately the docs don't explicitly state when there's an acknowledgement from the remote end point that it actually received that message...

In the end, as you concluded, TCP is a stream.

An interesting idea which just came up to me now, however, if you're FORCED TO use an existing protocol, then open two TCP connections.
When one connection acknowledges (whatever the higher-level protocol is) receiving that message, send the next through the other one... and so forth..

Anyway, nice challenge :)

Solution 2

I was wrong. TCP is a stream and the protocol works like a stream, but I didn't handle it like a stream.

PS: sending seperate messages seemed to work with setImmediate()

Share:
12,930
roeland
Author by

roeland

Updated on June 04, 2022

Comments

  • roeland
    roeland almost 2 years

    I'm implementing a tcp protocol in Node.

    Full source:
    https://github.com/roelandmoors/ads.js/blob/master/ads.js

    specs:
    http://infosys.beckhoff.com/content/1033/tcadsamsspec/html/tcadsamsspec_amstcppackage.htm?id=17754

    The problem is that I use this to send a package:

    this.tcpClient.write(buf);
    

    If I send multiple commands, then multiple commands are combined into a single tcp packet.
    This doesn't work.

    There are more questions about this on SO, but they recommend using a delimeter.
    But since I can't change the protocol this isn't an option.

    Isn't there a simple solution to flush the socket?

    socket.setNoDelay() doesn't help.

    Edit: I also tried to use the drain event to send the next write, but the event is never called?

    Update:

    This seems to solve the problem, but is very uggly and I don't now if it always works.
    Instead of writing it directly I write to a buffer:

    this.writeFILO.push(buf);
    

    Every cycle(?) I'm writing a package to the socket stream:

    var sendCycle = function(ads) {
        if (ads.writeFILO.length > 0) {
            ads.tcpClient.write(ads.writeFILO.shift());
        }
        setTimeout(function() {
            sendCycle(ads);
        }, 0);
    }
    
  • Barkermn01
    Barkermn01 over 4 years
    What is this setImmediate() i can't find anything out about it?
  • Jorge Fuentes González
    Jorge Fuentes González over 2 years
    @Barkermn01 well, it was very well documented. Just found a lot of posts from 2019 and pior, also from the very first NodeJS documentation alive (v0.10.x back in 2013), so whatever xD