How to Turn Your Device Into a Simple Server Using Node.js

Trix Cyrus - Sep 24 - - Dev Community

Author: Trix Cyrus

Let's create a simple Node.js server hosted from your device.

Getting Started

First, let's set up a basic server using Node.js. Follow these steps:

Create a directory named node-server:

mkdir node-server
cd node-server
Enter fullscreen mode Exit fullscreen mode

Initialize a new Node.js project:

npm init -y
Enter fullscreen mode Exit fullscreen mode

Install Dependencies:

npm install express ws multer mongoose dotenv helmet morgan cluster compression
Enter fullscreen mode Exit fullscreen mode

uses:
express: For handling HTTP requests.
ws: For WebSocket support.
multer: For file uploads.
mongoose: For MongoDB connection.
dotenv: For environment variables.
helmet: For security.
morgan: For logging.
cluster: For multi-threading.
compression: For compressing response data.

Create a .env File for Configuration.
In your project root, create a .env file for storing environment variables:

PORT=8080
MONGO_URI=mongodb://localhost:27017/serverdb
Enter fullscreen mode Exit fullscreen mode

Create a file named server.js:

touch server.js
nano server.js
Enter fullscreen mode Exit fullscreen mode

Paste the below script and save it

require('dotenv').config();
const express = require('express');
const ws = require('ws');
const http = require('http');
const multer = require('multer');
const mongoose = require('mongoose');
const helmet = require('helmet');
const morgan = require('morgan');
const cluster = require('cluster');
const os = require('os');
const compression = require('compression');
const fs = require('fs');
const path = require('path');

const PORT = process.env.PORT || 8080;
const MONGO_URI = process.env.MONGO_URI;
const NUM_CPUS = os.cpus().length;

if (cluster.isMaster) {
  console.log(`Master process is running. Spawning ${NUM_CPUS} workers...`);
  for (let i = 0; i < NUM_CPUS; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`Worker ${worker.process.pid} died. Spawning a new worker.`);
    cluster.fork();
  });
} else {
  const app = express();
  const server = http.createServer(app);
  const wss = new ws.Server({ server });

  mongoose.connect(MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true })
    .then(() => console.log('Connected to MongoDB'))
    .catch(err => console.error('MongoDB connection error:', err));

  app.use(express.json());
  app.use(helmet());
  app.use(morgan('common'));
  app.use(compression());

  const upload = multer({ dest: 'uploads/' });

  app.use(express.static(path.join(__dirname, 'public')));

  app.use((req, res, next) => {
    console.log(`Received ${req.method} request for ${req.url}`);
    next();
  });

  wss.on('connection', (socket) => {
    console.log('WebSocket connection established.');
    socket.on('message', (message) => {
      console.log(`Received WebSocket message: ${message}`);
      socket.send(`Message received: ${message}`);
    });
  });

  app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, 'public', 'index.html'));
  });

  app.get('/api/data', async (req, res) => {
    res.json({ message: 'Server API Response', data: [] });
  });

  app.post('/upload', upload.single('file'), (req, res) => {
    console.log('File uploaded:', req.file);
    res.status(201).json({ message: 'File uploaded successfully', file: req.file });
  });

  app.get('/greet/:name', (req, res) => {
    const name = req.params.name || 'stranger';
    res.send(`<h1>Hello, ${name}!</h1>`);
  });

  app.use((req, res, next) => {
    res.status(404).sendFile(path.join(__dirname, 'public', '404.html'));
  });

  app.use((err, req, res, next) => {
    console.error('Error encountered:', err);
    res.status(500).json({ error: 'An internal server error occurred' });
  });

  server.listen(PORT, () => {
    console.log(`Worker process ${process.pid} is running on port ${PORT}`);
  });
}
Enter fullscreen mode Exit fullscreen mode

Create a public directory with the following structure:

mkdir public
cd public
Enter fullscreen mode Exit fullscreen mode

index.html:

Basic HTML file for the homepage.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Node.js Server</title>
</head>
<body>
    <h1>Welcome to the node.js Server!</h1>
    <p>This server is a simple server.</p>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

404.html:

Custom 404 error page.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>404 - Page Not Found</title>
</head>
<body>
    <h1>404 - Page Not Found</h1>
    <p>The page you are looking for doesn't exist in this universe.</p>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Run the Server
Start the server:

node server.js
Enter fullscreen mode Exit fullscreen mode

Testing the Server Features

Real-Time Communication:
You can set up a WebSocket client to send messages to the server.

File Uploads:
Send a POST request to http://localhost:8080/upload with a file, and it will be saved to the uploads folder.

RESTful API:
Visit http://localhost:8080/api/data to see the API response.

Error Handling:
Visit any non-existent URL (e.g., http://localhost:8080/nonexistent) to see the custom 404 page.

Database:
Connect your server to a MongoDB instance and modify the /api/data route to query and return actual data.

final dir structure

node-server/
├── public/
│   ├── index.html
│   ├── 404.html
├── server.js
Enter fullscreen mode Exit fullscreen mode

And All Set

That's how you can create and run a simple Node.js server from your device! It’s a great way to learn the basics of backend development and see how servers work.

~TrixSec

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .