npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ipchannel

v0.2.8

Published

Elegant and self-hosting channel for inter-process communication.

Downloads

8

Readme

IPChannel

Elegant and self-hosting channel for inter-process communication.

Limits Of Ordinary IPC Modules

  1. NodeJS process.on("message") and process.send() only support messages from the master process to a child-process.
  2. Some situations, e.g. in PM2 cluster mode, developers don't have access to design logic in the master process.
  3. Third-party IPC modules often require starting the socket server manually, which often needs access to master process as well.
  4. Third-package IPC modules require setting exact socket protocol to communicate, which doesn't suit all environments. (e.g. cluster doesn't support Windows Named Pipe).
  5. Internal IPC support and many third-party packages doesn't generate predictable process id, you aren't able to send message to a certain process.
  6. One the master process or IPC server is down, all communications will be lost.

Advantages When Using IPChannel

  1. No need to access master process, even all the processes are executed manually (means they are not child-processes at all).
  2. No need to start IPC server explicitly, automatically choose the best protocol according to the environment.
  3. Communicate directly from one process to another or to all.
  4. With predictable peer id, you can distinguish processes from each other.
  5. When a process exited abnormally and restarted, the IPC channel will automatically rebuild with the same id.
  6. Even the internal IPC server is down, the remaining processes will ship a new one immediately and guarantee no-downtime period communication.
  7. Fully support under PM2 supervision.
  8. Sending messages event before the channel is connected.

How To Use?

It's as almost easy using this module as it will be when using internal process.on("message") and process.send(), and even more, IPChannel allows you sending messages with a custom event that emitted on the receiver side.

// task.js
import channel from "ipchannel";

// listening messages without event
channel.on("message", (sender, msg) => {
    console.log(`Peer ${sender} says: ${msg}`);
});

// By default, the channel is not connnected immediately, and `channel.pid` 
// (peer id) will only be available after the connection is established, so the 
// following code will output undefined since the channel is not open yet.
console.log(channel.pid); // => undefined

// If you check `channel.connected`, it will be false initially.
console.log(channel.connected); // => false

// Even the channel is not yet connected, you still can send messages now, they
// will be queued and flushed once the connection is established.
channel.to(1).send("This message is sent before connection.");

channel.on("connect", () => {
    // now that channel is connected
    console.log(channel.connected); // => true

    switch (channel.pid) {
        case 1:
            // listening messages with a custom event
            channel.on("custom-event", (sender, ...data) => {
                console.log(`Peer ${sender} emits: ${JSON.stringify(data)}`);
            });
            break;

        case 2:
            // send message to peer 1
            channel.to(1).send("Hi peer 1, I'm peer 2.");
            break;

        case 3:
            // send message with an event to peer 1
            channel.to(1).emit("custom-event", "hello world");
            break;

        case 4:
            // send message to all peers
            channel.to("all").send("all attention");
            // send message with an event to all peers
            channel.to("all").emit("custom-event", "all attention");
            break;
    }
});

In this example, I will use cluster to fork several child-processes, but using cluster is optional, you can just use child_process module as you want, or even run them manually (must provide the absolute path of the script file, e.g. node $(pwd)/task.js).

// index.js
const cluster = require("cluster");

if (cluster.isMaster) {
    // fork 4 workers
    for (let i = 0; i < 4; i++) {
        cluster.fork();
    }
} else {
    require("./task");
}

API

There are very few API in this package, it's designed to be as simple as possible, but brings the major IPC functionality across processes into NodeJS.

  • channel.connected: boolean Returns true if the channel is connected, false otherwise.
  • channel.pid: number Returns the peer id (starts from 1), this id will persist even after the process is restarted, but only available after connection.
  • channel.disconnect(): void Closes connection of the channel.
  • channel.on(event: "connect" | "disconnect", listener: () => void): this Binds a connection/disconnection handler.
  • channel.on(event: "error", listener: (err?: Error) => void): this Binds a error handler.
  • channel.on(event: "message", listener: (sender: number, msg: any) => void) Binds a listener function emitted when a message is sent to the current peer (channel.once() also works).
  • channel.on(event: string, listener: (sender: number, ...data) => void) Binds a listener function emitted when a message is sent to the current peer with a custom event (channel.once() also works).
  • channel.to(receiver: number | "all").send(...data): boolean Sends a message to the receiver, which could be a peer id, or broadcast to all peers (including the current one).
  • channel.to(receiver: number | "all").emit(event: string, ...data): boolean Sends a message to the receiver with a custom event, it could be a peer id, or broadcast to all peers (including the current one).

What Can't IPChannel Do?

  • IPChannel requires all processes run with the same entry file, it won't work with multi-entry applications.
  • IPChannel only supports communications on the same machine, it's not designed for network communications with remote services.
  • For efficiency concerns, IPChannel currently uses JSON to transfer data through the channel, those data cannot be serialized by JSON will be lost.

License

This package is licensed under MIT license.