0Pricing
Node.js Backend Development Bootcamp · 课时

构建实时聊天应用

开发功能完整的实时聊天应用,巩固对 WebSockets 和 Socket.IO 的理解。

构建实时聊天应用 是 CoddyKit 上的免费 Node.js Backend Development Bootcamp 课时。 这是第 5 节课,共 6 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Node.js Backend Development Bootcamp 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Node.js Backend Development Bootcamp 课程共包含 6 节课。

本课时的部分内容尚未翻译,以英文显示。

Build a Real-time Chat App

Welcome! In this lesson, we'll bring together your knowledge of WebSockets and Socket.IO to build a practical real-time chat application.

This hands-on project will solidify your understanding of how clients and servers communicate instantly, making live interactions possible.

Server Setup: Express & Socket.IO

First, let's set up our Node.js server using Express and integrate Socket.IO. This foundation will handle our HTTP requests for serving the HTML page and establish real-time WebSocket connections.

Remember to install dependencies: npm install express socket.io

const express = require('express');
const http = require('http');
const { Server } = require('socket.io');

const app = express();
const server = http.createServer(app);
const io = new Server(server);

// Serve our HTML file
app.get('/', (req, res) => {
  res.sendFile(__dirname + '/index.html');
});

// Listen for new Socket.IO connections
io.on('connection', (socket) => {
  console.log('A user connected');
});

// Start the server
server.listen(3000, () => {
  console.log('Listening on *:3000');
});

Handling User Connections

When a client successfully connects to our Socket.IO server, a 'connection' event is emitted. Similarly, when a client closes their browser or loses connection, a 'disconnect' event occurs.

These events allow us to track who is currently online.

const express = require('express');
const http = require('http');
const { Server } = require('socket.io');

const app = express();
const server = http.createServer(app);
const io = new Server(server);

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

io.on('connection', (socket) => {
  console.log('A user connected');

  // Listen for client disconnections
  socket.on('disconnect', () => {
    console.log('User disconnected');
  });
});

server.listen(3000, () => {
  console.log('Listening on *:3000');
});

Broadcasting Chat Messages

For a chat application, when one user sends a message, it needs to be seen by all other connected users. We achieve this by listening for a 'chat message' event from a client and then using io.emit() to broadcast it to everyone.

const express = require('express');
const http = require('http');
const { Server } = require('socket.io');

const app = express();
const server = http.createServer(app);
const io = new Server(server);

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

io.on('connection', (socket) => {
  console.log('A user connected');

  // Listen for 'chat message' from this client
  socket.on('chat message', (msg) => {
    console.log('message: ' + msg);
    io.emit('chat message', msg); // Broadcast to all connected clients
  });

  socket.on('disconnect', () => {
    console.log('User disconnected');
  });
});

server.listen(3000, () => {
  console.log('Listening on *:3000');
});

Client-Side HTML Structure

Now, let's create a simple index.html file. This will be the user interface for our chat application. It needs an input field to type messages and a list (<ul>) to display them.

Crucially, include the Socket.IO client library script via /socket.io/socket.io.js!

<!DOCTYPE html>
<html>
  <head>
    <title>CoddyKit Chat</title>
    <style>
      body { margin: 0; padding-bottom: 3rem; font-family: sans-serif; }
      #form { background: rgba(0, 0, 0, 0.15); padding: 0.25rem; position: fixed; bottom: 0; left: 0; right: 0; display: flex; height: 3rem; box-sizing: border-box; backdrop-filter: blur(10px); }
      #input { border: none; padding: 0 1rem; flex-grow: 1; border-radius: 2rem; margin: 0.25rem; }
      #input:focus { outline: none; }
      #form > button { background: #333; border: none; padding: 0 1rem; margin: 0.25rem; border-radius: 3px; outline: none; color: #fff; }
      #messages { list-style-type: none; margin: 0; padding: 0; }
      #messages > li { padding: 0.5rem 1rem; }
      #messages > li:nth-child(odd) { background: #eee; }
    </style>
  </head>
  <body>
    <ul id="messages"></ul>
    <form id="form">
      <input id="input" autocomplete="off" /><button>Send</button>
    </form>
    <script src="/socket.io/socket.io.js"></script>
    <!-- Client-side JavaScript will go here -->
  </body>
</html>

Client: Sending & Receiving Messages

Now, we add JavaScript to our index.html. This script will:

  • Connect to the Socket.IO server.
  • Emit a 'chat message' event when the form is submitted.
  • Listen for incoming 'chat message' events and display them.

The io() function automatically connects to the server where the script is served from.

<!-- ... (inside index.html, before </body>) ... -->
    <script src="/socket.io/socket.io.js"></script>
    <script>
      const socket = io(); // Connect to the Socket.IO server

      const form = document.getElementById('form');
      const input = document.getElementById('input');
      const messages = document.getElementById('messages');

      // Send message when form is submitted
      form.addEventListener('submit', (e) => {
        e.preventDefault(); // Prevent page reload
        if (input.value) {
          socket.emit('chat message', input.value); // Emit event to server
          input.value = ''; // Clear input field
        }
      });

      // Listen for incoming messages and display them
      socket.on('chat message', (msg) => {
        const item = document.createElement('li');
        item.textContent = msg;
        messages.appendChild(item);
        window.scrollTo(0, document.body.scrollHeight);
      });
    </script>
  </body>
</html>

Adding User Nicknames (Server)

To make the chat more personal, let's add user nicknames. On the server, we can store a nickname for each connected socket. We'll introduce a new event, 'set nickname', for clients to send their chosen name.

This nickname will then be included with their messages.

const express = require('express');
const http = require('http');
const { Server } = require('socket.io');

const app = express();
const server = http.createServer(app);
const io = new Server(server);

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

io.on('connection', (socket) => {
  let nickname = 'Anonymous'; // Default nickname for new connections

  socket.on('set nickname', (name) => {
    nickname = name;
    console.log(`${nickname} connected`);
    io.emit('chat message', `${nickname} joined the chat`);
  });

  socket.on('chat message', (msg) => {
    io.emit('chat message', `${nickname}: ${msg}`); // Prepend nickname to message
  });

  socket.on('disconnect', () => {
    console.log(`${nickname} disconnected`);
    io.emit('chat message', `${nickname} left the chat`);
  });
});

server.listen(3000, () => {
  console.log('Listening on *:3000');
});

Client: Setting & Displaying Nicknames

On the client side, we need to ask the user for a nickname when they first connect and then emit this to the server using our new 'set nickname' event. We'll also update the client-side display to show messages with the sender's nickname.

<!-- ... (inside index.html, before </body>) ... -->
    <script src="/socket.io/socket.io.js"></script>
    <script>
      const socket = io();

      const form = document.getElementById('form');
      const input = document.getElementById('input');
      const messages = document.getElementById('messages');

      // Prompt for nickname on connection
      let nickname = prompt('Please enter your nickname:');
      if (!nickname) nickname = 'Guest' + Math.floor(Math.random() * 1000);
      socket.emit('set nickname', nickname); // Send nickname to server

      form.addEventListener('submit', (e) => {
        e.preventDefault();
        if (input.value) {
          socket.emit('chat message', input.value);
          input.value = '';
        }
      });

      socket.on('chat message', (msg) => {
        const item = document.createElement('li');
        item.textContent = msg;
        messages.appendChild(item);
        window.scrollTo(0, document.body.scrollHeight);
      });
    </script>
  </body>
</html>

Tracking Online Users (Bonus)

To enhance our chat, let's add a feature to display who is currently online. The server can maintain a Set of active nicknames and broadcast this list whenever a user connects or disconnects.

Clients will listen for an 'online users' event to update their UI.

const express = require('express');
const http = require('http');
const { Server } = require('socket.io');

const app = express();
const server = http.createServer(app);
const io = new Server(server);

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

const onlineUsers = new Set(); // Store nicknames

io.on('connection', (socket) => {
  let nickname = 'Anonymous';

  socket.on('set nickname', (name) => {
    nickname = name;
    onlineUsers.add(nickname);
    io.emit('chat message', `${nickname} joined the chat`);
    io.emit('online users', Array.from(onlineUsers)); // Broadcast updated user list
  });

  socket.on('chat message', (msg) => {
    io.emit('chat message', `${nickname}: ${msg}`);
  });

  socket.on('disconnect', () => {
    onlineUsers.delete(nickname);
    io.emit('chat message', `${nickname} left the chat`);
    io.emit('online users', Array.from(onlineUsers)); // Broadcast updated user list
  });
});

server.listen(3000, () => {
  console.log('Listening on *:3000');
});

Chat App Workflow Check

Consider the complete flow of a message in our Socket.IO chat application, from one client sending it to all other clients receiving it.

Which of the following steps are essential for this real-time communication to occur?

Recap: Building a Chat App

Congratulations! You've successfully built a functional real-time chat application using Node.js, Express, and Socket.IO.

  • We set up the server to handle WebSocket connections and HTTP requests.
  • We implemented broadcasting to send messages to all connected users instantly.
  • We created a client-side interface to send and receive messages dynamically.
  • We enhanced the chat with user nicknames and real-time online user tracking.

This project demonstrates the power of WebSockets and Socket.IO for creating interactive, live experiences.

常见问题解答

「构建实时聊天应用」课时是免费的吗?

是的 — 「构建实时聊天应用」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Node.js Backend Development Bootcamp 课程的其余内容,请升级到 CoddyKit PRO。 Node.js Backend Development Bootcamp 课程共包含 6 节课。

「构建实时聊天应用」这节课中我会学到什么?

开发功能完整的实时聊天应用,巩固对 WebSockets 和 Socket.IO 的理解。 你通过在浏览器中直接运行的动手代码来练习 Node.js Backend Development Bootcamp,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Node.js Backend Development Bootcamp 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Node.js Backend Development Bootcamp 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 5 节课,共 6 节。

「构建实时聊天应用」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Node.js Backend Development Bootcamp 课中编写并运行代码吗?

能。每节 Node.js Backend Development Bootcamp 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. WebSockets 入门
  2. 使用 NestJS 实现 WebSockets
  3. 在 Node.js 中实现 Socket.IO
  4. 网关配置
  5. 构建实时聊天应用
  6. 实时聊天应用程序
← 返回 Node.js Backend Development Bootcamp