39

I have a C# application and a Node.js application. I would like to press a button in my C# application to send three arguments to a Node.js application/function as input. Is this possible?

Edit: Both applications run on the same machine. The C# application would provide three arguments to the Node.js application. The Node.js application would query a web service (POST), receive some XML data, and manipulate that data. I know that I could do that task in C# too, but in this case it has to be Node.js.

Edit #2 and solution: Right now I have chosen: 4. Your node process runs a socket server and your C# app does requests over tcp.

I will also provide a solution that seems to work:

Now you are ready to send any data from your C# application to the Node.js server.

Osama Rizwan
  • 615
  • 1
  • 7
  • 19
Gero
  • 12,993
  • 25
  • 65
  • 106
  • 6
    This should indeed be possible. If you have a specific question it would be wonderful if you attempted to do it, then asked, a specific question with regard to what you attempted. – Security Hound Feb 28 '13 at 13:41
  • 3
    How is your node.js app listening for requests? Are you listening for HTTP or TCP requests? Is it a command line app that you will launch from the C# app? – Hector Correa Feb 28 '13 at 13:43
  • @HectorCorrea I have not yet started with node.js. I wanted to be sure that a communication is feasible. The node.js application should run all the time and be ready to get some input from the c# application. – Gero Feb 28 '13 at 13:55
  • 1
    Do the applications run on the same machine? If yes, you want to look into inter-process communication (IPC). There are many IPC methods (pipes, files, sockets...) and the right choice depends on your specific requirements. For node.js IPC, see for instance http://stackoverflow.com/questions/6463945/whats-the-most-efficient-node-js-inter-process-communication-library-method. – Max Feb 28 '13 at 13:56
  • If your application will already be running you can easily communicate with it via HTTP. HTTP is supported in both C# and Node. HTTP might not be the most efficient way (depending on your requirements) but it certainly will be the easiest to get started and might even be enough for you long term. – Hector Correa Feb 28 '13 at 14:53
  • It seems that your problem can be solved with Inter Process Communication. (IPC) – Floby Feb 28 '13 at 15:06
  • 2
    You can take a look at this module. It may not exactly fit your needs but still pretty cool. [Edge.js](http://tjanczuk.github.io/edge/#/) > Run .NET and node.js code in-process – jackdbernier Aug 08 '13 at 19:15
  • You can use any form of IPC to connect between two processes be it nodejs app and your C# app or it can be any other such processes. You can also have a look at tjanczuk.github.io/edge/# – Robin Rizvi Apr 09 '14 at 18:03

2 Answers2

47

Yes communication is possible like several people have pointed out in your question's comments.

These are (some of) the options:

  1. Your node process runs an http server and your C# app does JSON Rest requests over http
  2. Your node process runs a SOAP webservice using the node-soap/strong-soap module
  3. C# app starts your node app and you do IPC by writing to the node process inputstream and read it's outputstream.
  4. Your node process runs a socket server and your C# app does requests over tcp.
  5. You use a 3rd process/server like Redis or a Message Queue
  6. Anything that allows you to share data like files..

I would recommend you go for the first option as that doesn't require you to define a language protocol to send over the "wire". The other reason would be that there is a lot of documentation available on doing Rest with C# and node.js.

As the client library in C# I would suggest you have a look at Restsharp as the client library if you can't use the latest version of .NET (4.5). If you can use the latest version, use HttpClient to call your Node.js restservice. For Node just use Express.

Option 2 might be quick as there is good support in VS for webservices, however, I have only used node-soap as a client so can't comment on how well the node-soap webservices are with C# clients.

Cody G
  • 8,368
  • 2
  • 35
  • 50
AndyD
  • 5,252
  • 35
  • 32
  • 1
    added node-soap as an option – AndyD Feb 28 '13 at 18:52
  • 2
    You can use any form of IPC to connect between two processes be it nodejs app and your C# app or it can be any such scenario. You can also have a look at http://tjanczuk.github.io/edge/#/ – Robin Rizvi Apr 09 '14 at 18:02
  • 1
    would it also be possible in C# to just use `process.start` and execute Node statements?(ex. `node start_test.js`) Is this a good idea? – Malcolm Salvador Jul 26 '18 at 14:50
6

Manually handling inter-process communication is time-consuming and the old alternative to that, Edge.js, has not been updated since mid 2017.

My organization maintains a library, Jering.Javascript.NodeJS, that allows you to call into Node.js from C#.

Example usage

string javascriptModule = @"
module.exports = (callback, x, y) => {  // Module must export a function that takes a callback as its first parameter
    var result = x + y; // Your javascript logic
    callback(null /* If an error occurred, provide an error object or message */, result); // Call the callback when you're done.
}";

// Invoke javascript in Node.js
int result = await StaticNodeJSService.InvokeFromStringAsync<int>(javascriptModule, args: new object[] { 3, 5 });

// result == 8
Assert.Equal(8, result);

You can invoke any valid Node.js module, including one that performs tasks like those listed in the question: querying a web service (POST), receiving XML data, and manipulating that data.

Highlights

  • Cross-platform support

    • Targets .NET Standard 2.0 and .NET Framework 4.6.1.
    • Tested on Windows, macOS and Linux.
  • Performance features

    • Does not start a new Node.js process for each invocation. Instead, sends invocations to long-lived processes via inter-process communication.
    • Optionally, runs invocations concurrently in a cluster of Node.js processes. Handles load balancing for the cluster.
    • Caches compiled javascript where possible.
  • Long-running application support

    • Restarts Node.js processes if they terminate unexpectedly.
    • Optionally, restarts Node.js processes on file change.
    • Kills Node.js processes when their parent .Net process dies.
  • Flexible API

    • Exposes both a static API and a dependency injection based API.
    • Supports invoking javascript in string form, Stream form, or from a file on disk.
JeremyTCD
  • 695
  • 1
  • 6
  • 11
  • Hi, is it possible to import npm packages in your library into javascript modules? I.e. say I want to import Puppeteer and do some stuff with it in js module, is it possible? Best Regards – user1665355 Jun 29 '20 at 07:24
  • Hey yeah it is, this example project wraps the PrismJS NPM package: https://github.com/JeringTech/Web.SyntaxHighlighters.Prism. This is the interop module: https://github.com/JeringTech/Web.SyntaxHighlighters.Prism/blob/master/src/Prism/Javascript/interop.js – JeremyTCD Jun 29 '20 at 11:14
  • ah ok great, maybe stupid question but is es6 module imports supported with packages import? Br – user1665355 Jun 29 '20 at 12:13
  • ES6 modules (import/export syntax) are experimental in the latest Node.js version (v14.4.0): https://nodejs.org/api/esm.html. To enable it, you can pass special arguments to Node.js or add an element to your package.json - refer to the [Node.js docs enabling section](https://nodejs.org/api/esm.html#esm_enabling) for details. Documentation on passing arguments to Node.js through Jering.Javascript.Nodejs: https://github.com/JeringTech/Javascript.NodeJS#nodejsprocessoptions. – JeremyTCD Jun 29 '20 at 14:45
  • 1
    i love this lib - integrated axios in one hour and it’s working absolutely stable! – jebbie Nov 01 '21 at 09:05
  • @jebbie would you mind sharing an example code please? :) – nicrie Feb 21 '22 at 11:27