Node.js and Raspberry Pi – Webserver with WebSocket

Welcome to The Coding College! In this tutorial, we’ll build a web server using Node.js and enhance it with WebSocket functionality. This project allows real-time communication between a web browser and a Raspberry Pi, making it perfect for interactive IoT projects.

What You’ll Learn

  1. How to create a web server on a Raspberry Pi using Node.js.
  2. How to implement WebSocket for real-time, bidirectional communication.
  3. Practical use cases, such as controlling GPIO pins or sending live data updates.

Prerequisites

  1. A Raspberry Pi with Node.js installed. (Follow our Node.js Setup Guide).
  2. Basic knowledge of JavaScript and Node.js.
  3. A computer or mobile device connected to the same network as the Raspberry Pi.

Hardware Requirements

  • Raspberry Pi with Wi-Fi or Ethernet connectivity.
  • (Optional) LEDs or sensors for GPIO interaction.

Installing Required Libraries

Install the following libraries for the project:

  1. Express: To create the web server.
  2. ws: To implement WebSocket.

Run the following command:

npm install express ws

Project Structure

Create the following file structure:

webserver/
│
├── server.js  # Node.js server code
├── public/
│   └── index.html  # Frontend code

Writing the Code

Step 1: Node.js Web Server with WebSocket

  1. Create a file named server.js:
const express = require('express');
const WebSocket = require('ws');
const http = require('http');

const app = express();
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });

// Serve static files
app.use(express.static('public'));

// Handle WebSocket connections
wss.on('connection', (ws) => {
    console.log('WebSocket connection established.');

    ws.on('message', (message) => {
        console.log('Received:', message);

        // Echo the message back to the client
        ws.send(`Server received: ${message}`);
    });

    ws.on('close', () => {
        console.log('WebSocket connection closed.');
    });
});

// Start the server
const PORT = 3000;
server.listen(PORT, () => {
    console.log(`Server running at http://localhost:${PORT}`);
});

Step 2: Frontend Code

  1. Create a file named index.html in the public folder:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebSocket Demo</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            text-align: center;
            margin-top: 50px;
        }
        input {
            padding: 10px;
            width: 300px;
            margin-bottom: 10px;
        }
        button {
            padding: 10px 20px;
            cursor: pointer;
        }
        #messages {
            margin-top: 20px;
            max-height: 300px;
            overflow-y: auto;
            border: 1px solid #ddd;
            padding: 10px;
        }
    </style>
</head>
<body>
    <h1>WebSocket Demo</h1>
    <input id="messageInput" type="text" placeholder="Type a message" />
    <button onclick="sendMessage()">Send</button>
    <div id="messages"></div>

    <script>
        const messagesDiv = document.getElementById('messages');
        const socket = new WebSocket(`ws://${location.hostname}:3000`);

        socket.onopen = () => {
            console.log('WebSocket connected.');
            displayMessage('Connected to server.');
        };

        socket.onmessage = (event) => {
            console.log('Message from server:', event.data);
            displayMessage(event.data);
        };

        socket.onclose = () => {
            displayMessage('WebSocket connection closed.');
        };

        function sendMessage() {
            const input = document.getElementById('messageInput');
            const message = input.value;
            socket.send(message);
            displayMessage(`You: ${message}`);
            input.value = '';
        }

        function displayMessage(message) {
            const messageElem = document.createElement('div');
            messageElem.textContent = message;
            messagesDiv.appendChild(messageElem);
        }
    </script>
</body>
</html>

Running the Server

  • Navigate to the project directory:
cd webserver
  • Start the server:
node server.js
  • Open a web browser and navigate to:
http://<your-raspberry-pi-ip>:3000

Testing WebSocket

  1. Type a message in the input box and press “Send”.
  2. The message will be sent to the server and echoed back to the client.

Enhancements

  1. GPIO Control: Add a button on the webpage to turn an LED on/off via WebSocket messages.
  2. Sensor Data Streaming: Stream live sensor data (e.g., temperature) from the Raspberry Pi to the webpage.
  3. Authentication: Secure the WebSocket connection using tokens.

Conclusion

By creating a web server with WebSocket, you’ve built the foundation for real-time communication in IoT projects. This setup allows you to remotely control Raspberry Pi GPIO pins or receive live updates from sensors.

For more interactive tutorials and projects, visit The Coding College.

Leave a Comment