Synchronous TCP Read in Node.js

Is there a way to do a synchronous read of a TCP socket in node.js?

I’m well aware of how to do it asynchronously by adding a callback to the socket’s ‘data’ event:

  • Parse large JSON file in Nodejs
  • Simple nodejs callback example with fs.readFile
  • Process timeout | Amazon Lambda to Firebase
  • ObjectID not storing hexadecimal value
  • Mongoose expand default validation
  • async for loop in node.js
  • socket.on('data', function(data) {
        // now we have the string data to do whatever with
    });
    

    I’m also aware that trying to block with a function call instead of registering callbacks goes against node’s design, but we are trying to update an old node module that acts as a client for my university while maintaining backwards compatibility. So we currently have:

    var someData = ourModule.getData();
    

    Where getData() previously had a bunch of logic behind it, but now we just want to send to the server “run getData()” and wait for the result. That way all logic is server side, and not duplicated client and server side. This module already maintains a TCP connection to the server so we are just piggybacking on that.

    Here are the solutions I’ve tried:

    1. Find a blocking read function for the socket hidden somewhere similar to python’s socket library within node’s net module.

      string_from_tcp = socket.recv(1024)
      

      The problem here is that it doesn’t seem to exist (unsurprisingly because it goes against node’s ideology).

    2. This syncnet module adds what I need, but has no Windows support; so I’d have to add that.

    3. Find a function that allow’s node to unblock the event loop, then return back, such that this works:

      var theData = null;
      clientSocket.on('data', function(data) {
          theData = data;
      });
      
      clientSocket.write("we want some data");
      
      while(theData === null) {
          someNodeFunctionThatUnblocksEventLoopThenReturnsHere(); // in this function node can check the tcp socket and call the above 'data' callback, thus changing the value of theData
      }
      
      // now theData should be something!
      

      Obvious problem here is that I don’t think such a thing exists.

    4. Use ECMAScript 6 generator functions:

      var stringFromTcp = yield socketRead(1024);
      

      The problem here is that we’d be forcing students to update their JavaScript clients to this new syntax and understanding ES6 is outside the scopes of the courses that use this.

    5. Use node-gyp and add to our node module an interface to a C++ TCP library that does support synchronous reads such as boost’s asio. This would probably work but getting the node module to compile with boost cross platform has been a huge pain. So I’ve come to Stack Overflow to make sure I’m not over-complicating this problem.

    In the simplest terms I’m just trying to create a command line JavaScript program that supports synchronous tcp reads.

    So any other ideas? And sorry in advance if this seems blasphemous in context of a node project, and thanks for any input.

  • socket.io assigning custom socket.id
  • How to disable 'withcredentials' in HTTP header with node.js and Request package?
  • What are the proper use cases for process.nextTick in Node.js?
  • Browserify “module is not defined”
  • Best practice to hang on to variables when using Promises
  • angularjs app web.js structure to deploy on heroku
  • One Solution collect form web for “Synchronous TCP Read in Node.js”

    I ended up going with option 5. I found a small, fast, and easy to build TCP library in C++ (netLink) and wrote a node module wrapper for it, aptly titled netlinkwrapper.

    The module builds on Windows and Linux, but as it is a C++ addon you’ll need node-gyp configured to build it.

    I hope no one else has to screw with Node.js as I did using this module, but if you must block the event loop with TCP calls this is probably your only bet.

    Node.js is the Best Javascript runtime in the world.