Skip to content

Instantly share code, notes, and snippets.

@kevinswiber
Created November 23, 2011 23:05
Show Gist options
  • Save kevinswiber/1390198 to your computer and use it in GitHub Desktop.
Save kevinswiber/1390198 to your computer and use it in GitHub Desktop.
Passing messages between Node.js and C#.
using System;
using System.Text;
namespace NodeIPC
{
class Program
{
static void Main(string[] args)
{
var input = Console.OpenStandardInput();
var buffer = new byte[1024];
int length;
while (input.CanRead && (length = input.Read(buffer, 0, buffer.Length)) > 0)
{
var payload = new byte[length];
Buffer.BlockCopy(buffer, 0, payload, 0, length);
Console.Write("Receiving: " + Encoding.UTF8.GetString(payload));
Console.Out.Flush();
}
}
}
}
// run `node server.js` with NodeIPC.exe in the same directory.
var spawn = require('child_process').spawn;
var ipc = spawn("./NodeIPC.exe");
ipc.stdin.setEncoding("utf8");
ipc.stderr.on('data', function (data) {
process.stdout.write(data.toString());
});
ipc.stdout.on('data', function (data) {
process.stdout.write(data.toString());
});
var message = { type: "Greeting", data: "Hello, World!" };
console.log("Sending: ", JSON.stringify(message));
ipc.stdin.write(JSON.stringify(message) + "\n");
// to allow sending messages by typing into the console window.
var stdin = process.openStdin();
stdin.on('data', function (data) {
ipc.stdin.write(data);
});
@ayshamusthak76
Copy link

Thanks for the code!!

For the people asking steps, here's how:

  1. Build your CS file to get the .exe file. I used Visual Studio 2022 with CS installed.
  2. Put the .exe file in the same folder/directory as your JS file.
  3. Run the js code.

@jonathan-annett
Copy link

I converted the example into a wrapper function with event callbacks, and made a test/build script which includes a link to a framework compiler for those who don't have it already installed.

server.js

function ipcTask(path) { 

    const events = { error: [], message: [], send:[],exit: [] } ;
    const spawn = require('child_process').spawn;   

    const ipc = spawn(path); 

    let closed = false;

    ipc.stdin.setEncoding("utf8");

    ipc.stderr.on('data', function (data) {
        emit('error',data.toString());
    });

    ipc.stdout.on('data', function (data) {
        const json = data.toString();
        try {
            emit('message',JSON.parse(json));
        } catch (err) {
            emit('error',err);
        }
    });

    ipc.on('exit', function () {
        closed=true;
        emit('exit');
    });

    function on(ev,fn) {
        if (typeof ev+typeof fn+ typeof events[ev] === 'stringfunctionobject') {
            const stack = events[ev],ix=stack.indexOf(fn);
            if (ix<0) stack.push(fn);            
        }
    }

    function off(ev,fn) {
        if (typeof ev+typeof fn+ typeof events[ev] === 'stringfunctionobject') {
            const stack = events[ev],ix=stack.indexOf(fn);
            if (ix>=0) stack.splice(ix,1);            
        }
    }

    function emit(ev) {
        const stack = events[ev];
        if (Array.isArray(stack)) {
            const args = [].slice.call(arguments,1);
            stack.forEach(function(fn){
                fn.apply(null,args);
            });
        }
    }

    function send(msg) {
        if (closed) throw new Error ("Attempt to send to client that has exited");
        ipc.stdin.write(JSON.stringify(msg) + "\n");
        emit('send',msg);
    }


    function close() {
        try {
            ipc.kill(); 
        } catch (err) {
            console.log(err);
        }
    }

    return {
        on,
        off,
        send,
        close
    };
}

const clientIPC = ipcTask("./client.exe");

let tmr = setInterval(function(){
    clientIPC.send({now:Date.now()});
},1000);


clientIPC.on('message',function(msg){
    console.log('from client:',msg);
});

clientIPC.on('send',function(msg){
    console.log('sent to client:',msg);
});

clientIPC.on('exit',function(){
    console.log('client exited');
    clearInterval(tmr);
});

var message = { type: "Greeting", data: "Hello, World!" };

clientIPC.send(message);


setTimeout(function(){
    clientIPC.close();
},5000);

test.cmd

@echo off
if not exist C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe goto no_dotnet
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe  /out:client.exe .\Program.cs >./compile.log
node ./server.js
goto done
:no_dotnet
echo see https://dotnet.microsoft.com/en-us/download/dotnet-framework/net481 for a framework
:done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment