2

I have a C code, that within a infinite loop waits for an input and produces an output.

#include<stdio.h>
void flush() {
    int c;
    while ((c = getchar()) != '\n' && c != EOF);
}

int main() {
    /*
     *  Load many files here
     */
    double d = 0;
    char input[1024];
    while (1) {
        d = d + 0.1;
        scanf("%[^\n]", input);        
        printf("%lf\n",d);
        fflush(stdout);
        flush();

    }
}

I need another Node JS service that will listen to on some port and send the output as response. I have this code written

var http = require('http');


var spawn = require('child_process').spawn;

var child = spawn('./dummyNLU.out');
child.stdin.setEncoding('utf-8');
child.stdin.cork();
var buffer = new Buffer(100);
var app = http.createServer(function(req,res){
    var string = buffer.write("HelloWorld!"); //this is for testing purpose
    child.stdin.write(buffer);
    child.stdin.end();
    child.stdout.on('data', function(data) {
        res.setHeader('Content-Type', 'text/plain');
        res.end(data);
    });
});

app.listen(3001);

This code I have doesn't seem seem working at all.

Node JS server terminates with an error and the web response consist of 283 lines of response instead of 1.

Can anyone please help me?? Some other approaches to solve the problem (reply to web request from a C executable code output) are also welcome. Thank you in advance.

1
  • The first request will close the stdin of the child. How do you expect the second request to be served? Commented Aug 28, 2017 at 8:20

1 Answer 1

3

child_process.spawn

Spawn your C code binary as a child from Node (bidirectional communication)

var spawn = require('child_process').spawn
var child = spawn('main.exe')   
child.stdin.end('7')
child.stdout.on('data', (data) => { console.log(data); })
child.on('close', (code) => console.log('Exit code: ' + code))

This can be tricky if its receiving multiple simultaneos requests, You will need to track the client (origin request) to do the correct response (answer to the correct requesting client)

Or make a queu and spawn a children for each request (having a maximum of X simultaneos children working at a time) so they are spawned as requested and killed once not needed (having the queu is to throttle the total number of active C process)

PoC node spawning a child command (ls) and printing the result (stdout of the spawned process)

    const spawn = require('child_process').spawn 
    const C = spawn('ls');let r='' 
    C.stdout.on('data',d=>r+=d) 
    C.on('close', () => console.log(r)); 

streaming-worker

designed to give you a simple interface for sending and receiving events/messages from a long running asynchronous C++ Node.js Addon.

Streaming data from C to Node.js

Sign up to request clarification or add additional context in comments.

6 Comments

'child.stdin.end('7')' makes my c code fall in an infinite loop. stdin does not net consumed but remains in the stdin buffer
try using child.stdin.write instead
In that case child.stdout.on('data', function) is not triggered
check the code : added a proof of concept of how to spawn a child and output the data of the child process (also remember that maybe you need to add a line termination character \n for your C binary to actually process the line of data you sent with the .write)
This works well with codes (I mean C code) that terminates after giving the output. If you look into my C code. You will find that the scanf() is called within a infinite while loop. I have to do this because the C code need to load several files into the memory, which may cause significant overhead if I spawn the executable (Compiled from C code) every time the server gets a data. Any help would be appreciated :)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.