Categories
JavaScript Answers

How to scale socket.IO to multiple Node.js processes using cluster?

Sometimes, we want to scale socket.IO to multiple Node.js processes using cluster.

In this article, we’ll look at how to scale socket.IO to multiple Node.js processes using cluster.

How to scale socket.IO to multiple Node.js processes using cluster?

To scale socket.IO to multiple Node.js processes using cluster, we can use cluster to create workers processes.

For instance, we write

const cluster = require("cluster");
const os = require("os");

if (cluster.isMaster) {
  const server = require("http").createServer();
  const io = require("socket.io").listen(server);

  const RedisStore = require("socket.io/lib/stores/redis");
  const redis = require("socket.io/node_modules/redis");

  io.set(
    "store",
    new RedisStore({
      redisPub: redis.createClient(),
      redisSub: redis.createClient(),
      redisClient: redis.createClient(),
    })
  );

  setInterval(function () {
    io.sockets.emit("data", "payload");
  }, 1000);

  for (let i = 0; i < os.cpus().length; i++) {
    cluster.fork();
  }

  cluster.on("exit", (worker, code, signal) => {
    console.log("worker " + worker.process.pid + " died");
  });
}

if (cluster.isWorker) {
  const express = require("express");
  const app = express();

  const http = require("http");
  const server = http.createServer(app);
  const io = require("socket.io").listen(server);

  const RedisStore = require("socket.io/lib/stores/redis");
  const redis = require("socket.io/node_modules/redis");

  io.set(
    "store",
    new RedisStore({
      redisPub: redis.createClient(),
      redisSub: redis.createClient(),
      redisClient: redis.createClient(),
    })
  );

  io.sockets.on("connection", (socket) => {
    socket.emit("data", "connected to worker: " + cluster.worker.id);
  });

  app.listen(80);
}

to create a server on the master with

const server = require('http').createServer();

Then we call cluster.fork(); to create worker processes.

Then we create express servers on the workers with

const server = http.createServer(app);

We use Redis to do the caching with both the cluster master and worker.

Conclusion

To scale socket.IO to multiple Node.js processes using cluster, we can use cluster to create workers processes.

Categories
JavaScript Answers

How to download a file to disk from an AWS S3 bucket with Node.js?

Sometimes, we want to download a file to disk from an AWS S3 bucket with Node.js.

In this article, we’ll look at how to download a file to disk from an AWS S3 bucket with Node.js.

How to download a file to disk from an AWS S3 bucket with Node.js?

To download a file to disk from an AWS S3 bucket with Node.js, we can create a read steam from the S3 client.

For instance, we write

const AWS = require("aws-sdk");
const path = require("path");
const fs = require("fs");

AWS.config.loadFromPath(path.resolve(__dirname, "config.json"));
AWS.config.update({
  accessKeyId: AWS.config.credentials.accessKeyId,
  secretAccessKey: AWS.config.credentials.secretAccessKey,
  region: AWS.config.region,
});

const s3 = new AWS.S3();
const params = {
  Bucket: "<your-bucket>",
  Key: "<path-to-your-file>",
};
const readStream = s3.getObject(params).createReadStream();
const writeStream = fs.createWriteStream(path.join(__dirname, "s3data.txt"));
readStream.pipe(writeStream);

to call s3.getObject to get the object from the bucket.

Then we call createReadStream from the returned object to read the file.

Next, we call fs.createWriteStream with the path to write to.

And then we call readStream.pipe with the writeStream to pipe the read stream data into the write stream to write the file to disk.

Conclusion

To download a file to disk from an AWS S3 bucket with Node.js, we can create a read steam from the S3 client.

Categories
JavaScript Answers

How to fix the “Typescript Error: Property ‘user’ does not exist on type ‘Request'” error with Express?

To fix the "Typescript Error: Property ‘user’ does not exist on type ‘Request’" error with Express, we can add our own definition for the request type.

For instance, we add

IGetUserAuthInfoRequest.ts

import { Request } from "express";
export interface IGetUserAuthInfoRequest extends Request {
  user: string;
}

into a TypeScript type definition file.

We create the IGetUserAuthInfoRequest interface the extends the Request interface by adding the user field.

Then we use it by writing

import { Response } from "express";
import { IGetUserAuthInfoRequest } from "./IGetUserAuthInfoRequest";

app.get(
  "/auth/userInfo",
  validateUser,
  (req: IGetUserAuthInfoRequest, res: Response) => {
    res.status(200).json(req.user);
  }
);

to import IGetUserAuthInfoRequest and use it as the type for the req parameter instead of Request.

Categories
JavaScript Answers

How to do server-side browser detection with Node.js?

Sometimes, we want to do server-side browser detection with Node.js

In this article, we’ll look at how to do server-side browser detection with Node.js.

How to do server-side browser detection with Node.js?

To do server-side browser detection with Node.js, we can use the ua-parser-js package.

To install it, we run

npm i ua-parser-js

Then we use it by writing

const UAParser = require("ua-parser-js");
//...
const ensureLatestBrowser = (req, res, next) => {
  const parser = new UAParser();
  const ua = req.headers["user-agent"];
  const browserName = parser.setUA(ua).getBrowser().name;
  const fullBrowserVersion = parser.setUA(ua).getBrowser().version;
  //...
  return next();
};

app.all(/^(?!(\/update)).*$/, ensureLatestBrowser);

to create a new UAParser instance.

Then we get the user-agent request header value with req.headers["user-agent"].

Next, we call setUA with the ua user agent string to parse the user agent string.

And then we call getBrowser on the parsed user agent object to get various parts of the user agent string to get the browser name, version, etc.

Conclusion

To do server-side browser detection with Node.js, we can use the ua-parser-js package.

Categories
JavaScript Answers

How to fix the writeFile ‘no such file or directory’ error in Node.js?

Sometimes, we want to fix the writeFile ‘no such file or directory’ error in Node.js.

In this article, we’ll look at how to fix the writeFile ‘no such file or directory’ error in Node.js.

How to fix the writeFile ‘no such file or directory’ error in Node.js?

To fix the writeFile ‘no such file or directory’ error in Node.js, we can call mkdirp to create the folder before we call writeFile to make sure the directory we’re writing to exists.

For instance, we write

const mkdirp = require("mkdirp");
const fs = require("fs");

const writeFile = async (path, content) => {
  await mkdirp(path);
  fs.writeFileSync(path, content);
};

to call mkdirp with the path to create the folder as the path if it doesn’t exist.

Then we call fs.writeFileSync to write the file to the path.

Conclusion

To fix the writeFile ‘no such file or directory’ error in Node.js, we can call mkdirp to create the folder before we call writeFile to make sure the directory we’re writing to exists.