DEV Community

Cover image for I made an Express-like framework for IPC communication
Muhammad Sifat Hossain
Muhammad Sifat Hossain

Posted on

I made an Express-like framework for IPC communication

For the past two months, I've been developing a CLI (Command Line Interface)
Pomodoro timer and Todo application with Node.js. It will also have a TUI (Text
User Interface) to show statistics with various graphs and charts.

The main idea is: It should be able to create countdown timers and when a timer
finishes it'll give an alarm to remind me to take a break from work. Beside
that, it'll keep logs of my work sessions to show various stats.

It has the following architecture:

+-----------+  +--------+  +---------+
|DB (Sqlite)|  | Timer  |  | Speaker |
+-----------+  +--------+  +---------+
             \     |      /
              \    |     /
             +-----------+
             |   Server  |
             +-----------+
              |^      |^
              ||      ||
              v|      v|
           +-----+  +-----+
           | CLI |  | TUI |
           +-----+  +-----+
Enter fullscreen mode Exit fullscreen mode

The Server runs in the background as a service. The CLI and the TUI
communicates with the server over the IPC (TCP over Unix domain
socket
or Windows Named Pipe) protocol. The server also needs to able to
broadcast data to it's client.

Though, I can just use a raw socket server with net.createServer to do this
communication but it gets a little complicated after a while. Just as you
wouldn't use http.createServer instead of a framework like Express, I
couldn't go further with this approach.

So, I decided to create my own IPC server framework (as a fun challenge) with
two goals in mind:

  1. Request handling feature like Express
  2. Data broadcasting to multiple clients

Alhamdulillah (praise be to God) after two weeks of work today I have published
the framework on npm. I named it Express-IPC.

See it on GitHub and NPM.

Example usages:

server.js

const { Server } = require("express-ipc");

const socketPath = "./pipe";
const server = new Server();

const users = [
  { id: 1, name: "Alex" },
  { id: 2, name: "Alexa" },
];

server.get("/users/:id", ({ req, res }) => {
  const id = Number(req.params.id);
  const user = users.find((user) => user.id === id);

  if (user) res.send(user);
  else res.send({ message: `No user found with id: ${id}` }, { isError: true });
});

server.listen({
  path: socketPath,
  deleteSocketBeforeListening: true,
  callback() {
    console.log(`Server running on socket: ${server.socketPath}`);
  },
});
Enter fullscreen mode Exit fullscreen mode

client.js

const { Client } = require("express-ipc");
const socketPath = "./pipe";

main();

async function main() {
  const client = new Client({ path: socketPath });

  try {
    const response = await client.get("/users/1");
    console.log(response);
  } catch (ex) {
    console.log(ex);
  }

  client.close();
}
Enter fullscreen mode Exit fullscreen mode

The toughest part was the request routing algorithm.

Flow chart of request routing

Sorry, it's too big to fit here and Dev.to doesn't support SVG files. I
tried to embed the flowchart here but it seems like, Dev.to neither supports
Mermaid nor can load my GitHub gist
about the flowchart. See the full chart
here.

Alhamdulillah, I was able to solve it after making a flowchart of the algorithm.
Honestly, It was super boring and took almost a day for me to solve.

As the server framework is completed, now it times for me to go back and
integrate it into my Pomodoro application.

I would love to hear your thoughts about this framework. If you have any
suggestion or feedback please let me know in the comment section 💝.

Credits: The background image is taken from Unsplash

Oldest comments (0)