Search code examples
.netnode.jsipcnamed-pipes

Named Pipe Communication between Node.js and .net


I am working on an inter-process communication between a .net (v4.5.2) and Javascript node.js (v8.9.0) application. I want to use Windows named pipes for this (and only named pipes). For the Javascript application, I am using the named-pipes package (v0.0.1) I am able to establish a connection between the two applications which tells me that I am not completely off base here. I would expect to see the data event being triggered in the JavaScript application whenever I am writing a string to the NamedPipeServerStream but no data is received. I can not receive any data. Here is the code for .net and the JavaScript application. Any ideas why the data event is not being triggered?

.Net Code

using System;
using System.IO;
using System.IO.Pipes;

namespace NamedPipes
{
    class Program
    {
        static void Main(string[] args)
        {
            var server = new NamedPipeServerStream("XYZNamedPipe");

            Console.WriteLine("Waiting for Connection");
            server.WaitForConnection();
            Console.WriteLine("Connection Established");
            StreamWriter writer = new StreamWriter(server);

            int cnt = 0;
            while (true)
            {
                string line = Console.ReadLine();
                writer.WriteLine(++cnt.ToString() + ": " + line);
            }
        }
    }
}

JavaScript Code

var NamedPipes = require("named-pipes");
pipe = NamedPipes.connect('XYZNamedPipe')

pipe.on('connect', (str) => {
    console.log('connection established'); 
});

pipe.on('data', (str) => {
    console.log('data received');   
    console.log(str); 
});

pipe.on('end', (str) => {
    console.log('end');       
});

Solution

  • There are two reasons, why the data event is not triggered:

    1. The "named-pipes" package is internally creating sub-pipes. This package is easy to use, if you create the server with the same package. But in this case the pipe server is created via a .net application. So in the javascript code you better use the "net" module of Node.js to connect to the server.

    2. In the .net application you should not create a new StreamWriter. Just use the write method of the server instance. The NamedPipeServerStream implements IDisposable, so it is better to put it in a using block.

    .Net Code

      static void Main(string[] args)
        {
            using (NamedPipeServerStream server = new NamedPipeServerStream("XYZNamedPipe"))
            {
                Console.WriteLine("Waiting for Connection");
                server.WaitForConnection();
                Console.WriteLine("Connection Established");
    
                int cnt = 0;
                while (true)
                {
                    string line = Console.ReadLine();
                    byte[] messageBytes = Encoding.UTF8.GetBytes((++cnt).ToString() + ": " + line);
                    server.Write(messageBytes, 0, messageBytes.Length);
                }
            }
        }
    

    JavaScript Code

    const net = require('net');
    
    const PIPE_NAME = 'XYZNamedPipe';
    const PIPE_PATH = '\\\\.\\pipe\\';
    
    const client = net.createConnection(PIPE_PATH + PIPE_NAME, () => {
      console.log('connected to server!');
    });
    
    client.on('data', (data) => {
      console.log(data.toString());
    });
    
    client.on('end', () => {
      console.log('disconnected from server');
    });