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 patibility. 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:
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).
This syncnet module adds what I need, but has no Windows support; so I'd have to add that.
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.
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.
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 pile with boost cross platform has been a huge pain. So I've e to Stack Overflow to make sure I'm not over-plicating this problem.
In the simplest terms I'm just trying to create a mand 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.
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 patibility. 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:
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).
This syncnet module adds what I need, but has no Windows support; so I'd have to add that.
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.
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.
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 pile with boost cross platform has been a huge pain. So I've e to Stack Overflow to make sure I'm not over-plicating this problem.
In the simplest terms I'm just trying to create a mand 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.
Share Improve this question asked Aug 13, 2015 at 19:13 JacobFischerJacobFischer 7231 gold badge8 silver badges15 bronze badges 6- 1 This may help – ODelibalta Commented Aug 13, 2015 at 19:16
- Thanks, but I don't think socket.io could do anything for my problem. It would just fire asyncronous events when the whole point is that I'm trying to get data from a server synchronously in code. – JacobFischer Commented Aug 13, 2015 at 19:46
-
Oh I see... I just did some web search. This one has a
sync:true
option. It may help. I did not fully read it. Good luck. – ODelibalta Commented Aug 13, 2015 at 19:54 -
So you have a function
getData()
that establishes a connection with a server, gets some data, and returns it? And this was all implemented synchronously? What platform were you executing this code before? – Yuri Zarubin Commented Aug 14, 2015 at 1:48 -
Thanks ODelibalta for the heads up on that flag. It didn't appear to change anything but I'll dig through the net module's source to try to figure out where flags are used for hints. A TCP connection is already established. All this does is send some data over TCP and expects the next data the server sends over the opened TCP socket to be the response. Currently clients have a copy of the server logic to know what to expect from
getData()
, but implementing the logic on both clients and servers is tedious each semester, so we're trying to now ask the server to run it and give us the result. – JacobFischer Commented Aug 14, 2015 at 2:25
1 Answer
Reset to default 8I 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.