Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

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.

like image 278
JacobFischer Avatar asked Aug 13 '15 19:08

JacobFischer


People also ask

Does NodeJS support synchronous?

Or as Node. js docs puts it, blocking is when the execution of additional JavaScript in the Node. js process must wait until a non-JavaScript operation completes. Blocking methods execute synchronously while non-blocking methods execute asynchronously.

Is NodeJS synchronous by default?

To provide concurrency, time-consuming operations (in particular I/O events and I/O callbacks) in Node. js are asynchronous by default. In order to achieve this asynchronous behavior, modern Node. js utilizes the event loop as a central dispatcher that routes requests to C++ and returns those results to JavaScript.

How do I create a TCP connection in NodeJS?

Like the TCP client, to set up the TCP server, we will use the “net” module. After starting it, the server will listen on a specific port (8888 in this example) and will: wait for a client connection. receive data from each connected client.

Is NodeJS always asynchronous?

js is an asynchronous event-driven JavaScript runtime and is the most effective when building scalable network applications. Node. js is free of locks, so there's no chance to dead-lock any process. asynchronous operations: async.


1 Answers

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.

like image 115
JacobFischer Avatar answered Sep 24 '22 06:09

JacobFischer