Giter VIP home page Giter VIP logo

named-pipes's Introduction

This package allows you to work with named pipes to write to or read from. You can listen to arbitrary named pipes, or you can create named pipes and write to them. It works on both Windows using net.Socket and Unix using mkfifo.

Installation

Using yarn:

$ yarn add @kldzj/named-pipes

Using npm:

$ npm i -S @kldzj/named-pipes

Example usage

import { createNamedPipe } from '@kldzj/named-pipes';

// You may also name the pipe yourself,
// or even pass a writable absolute path.
const pipe = createNamedPipe(/* '/var/cool.sock', 0o640 */);
console.log('Path to socket:', pipe.path);

const sender = pipe.createSender();
const receiver = pipe.createReceiver();

// sender.connect() will create the pipe
await sender.connect();
// receiver.connect() will fail if the pipe does not exist
await receiver.connect();

// handle data
receiver.on('data', (c) => console.log(c.toString()));
// or pipe it somewhere
// receiver.getReadableStream().pipe(someDestinationStream);

// Sender might not be ready yet,
// wait for socket to be connected
sender.once('connected', () => {
  // use the convenience write method
  sender.write('hello world');
  // or create a writable stream and pipe to it
  // someSourceStream.pipe(sender.getWritableStream());
});

// once you're done, destroy the pipe
await pipe.destroy();

View example on RunKit

Notes

It is recommended to use the createNamedPipe function instead of using the exported classes directly.

The order in which you connect the sender and receiver is important. If you are writing to a pipe and then reading from it, you should connect the sender first.

If you intend on only reading from a pipe, you do not need a sender. Vice versa, if you intend on only write to a pipe, you do not need a receiver.

createNamedPipe(name?: string, mode?: number)

In case the pipe name is not an absolute path, the pipe will be created in the os tmp directory. If the pipe name is omitted, a random name will be generated.

On Windows, the mode is ignored.

NamedPipe

Is a reference to a named pipe. You can use it to create a sender or receiver, or to destroy the pipe. On its own, it's not going to do anything. You can use the .path property to get the absolute path.

To actually create a named pipe you need to create a Sender using .createSender(). Returns SocketSender on Windows and FIFOSender on Unix.

To listen to a named pipe you need to create a Receiver using .createReceiver(). Returns SocketReceiver on Windows and FIFOReceiver on Unix.

.exists() should be used to check if the pipe exists before creating a Receiver.

.destroy() will destroy all the receivers, the sender and all its existing connections.

Sender

The sender will create a socket server on Windows or a FIFO on Unix and listen for incoming connections on the specified path. There will be a maximum of one sender per pipe. You must call .connect() to actually create the socket.

Important: The sender might not be ready after the .connect() promise has resolved, so you should use the .once('connect', () => {}) event to wait for the socket to be connected before writing, otherwise you'll have thread blocking issues.

Use .getWritableStream() to get a writable stream that you can pipe to.

It will fail to connect (start the server) if:

  • the path is already in use
  • the path is not writable

Receiver

The receiver will create a socket client and connect to the specified path. You must call .connect() before you can start reading.

Use .getReadableStream() to get a readable stream that you can pipe somewhere.

It will fail to connect if:

  • the path does not exist
  • the path is not readable
  • the path is not a socket

named-pipes's People

Contributors

dependabot[bot] avatar kldzj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

cyberflamego

named-pipes's Issues

Connect pipe timeout on Windows

Hello:

So glad to find this awesome module ๐Ÿคฉ๐Ÿคฉ

I'm trying to use named pipes between a Javascript application and a Python application on Windows. I created a server in the Python application, but when I tried to connect it in the Javascript application via createNamedPipe('Foo').createReceiver().connect(), I got a timeout error: Error: connect ETIMEDOUT \\.\pipe\Foo at PipeConnectWrap.afterConnect [as oncomplete] (net.js:1134:16).

The following is the Python application(just a script) I used:

# #!/usr/bin/python3
# #-*- coding:utf-8 -*-

import time
import sys
import win32pipe, win32file, pywintypes


def pipe_server():
    print("pipe server")
    count = 0
    pipe = win32pipe.CreateNamedPipe(
        r'\\.\pipe\Foo',
        win32pipe.PIPE_ACCESS_DUPLEX,
        win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_READMODE_MESSAGE | win32pipe.PIPE_WAIT,
        1, 65536, 65536,
        0,
        None)
    try:
        print("waiting for client")
        win32pipe.ConnectNamedPipe(pipe, None)
        print("got client")

        while count < 10:
            print(f"writing message {count}")
            # convert to bytes
            some_data = str.encode(f"{count}")
            win32file.WriteFile(pipe, some_data)
            time.sleep(1)
            count += 1

        print("finished now")
    finally:
        win32file.CloseHandle(pipe)


def pipe_client():
    print("pipe client")
    quit = False

    while not quit:
        try:
            handle = win32file.CreateFile(
                r'\\.\pipe\Foo',
                win32file.GENERIC_READ | win32file.GENERIC_WRITE,
                0,
                None,
                win32file.OPEN_EXISTING,
                0,
                None
            )
            res = win32pipe.SetNamedPipeHandleState(handle, win32pipe.PIPE_READMODE_MESSAGE, None, None)
            if res == 0:
                print(f"SetNamedPipeHandleState return code: {res}")
            while True:
                resp = win32file.ReadFile(handle, 64*1024)
                print(f"message: {resp}")
        except pywintypes.error as e:
            if e.args[0] == 2:
                print("no pipe, trying again in a sec")
                time.sleep(1)
            elif e.args[0] == 109:
                print("broken pipe, bye bye")
                quit = True


if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("need s or c as argument")
    elif sys.argv[1] == "s":
        pipe_server()
    elif sys.argv[1] == "c":
        pipe_client()
    else:
        print(f"no can do: {sys.argv[1]}")

And my Javascript application code:

    async test(): Promise<void> {
        const pipe = createNamedPipe('Foo');
        const receiver = pipe.createReceiver();

        while (true) {
            console.log('Try to connect the receiver pipe...');
            try {
                await receiver.connect();
                console.log('Receiver pipe connect successfully');
                break;
            } catch {
            }
        }

        receiver.on('data', (chunk: Buffer) => {
            console.log('Received data from python server: ', chunk.toString());
        });
    }

I don't know why I get the timeout error when I use createNamedPipe('Foo').createReceiver().connect() ๐Ÿ˜ข

BTW: I tested another NodeJS script using the net module and connected it to the Python server and it worked fine:

const net = require('net');

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

image

How can I fix the timeout error?

Really appreciate!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.