首頁  >  文章  >  web前端  >  用nodejs搭建聊天室

用nodejs搭建聊天室

WBOY
WBOY原創
2023-05-24 12:23:38945瀏覽

隨著網路的快速發展,人們之間的溝通方式也不斷改變。聊天室是一種線上的即時通訊應用,它讓使用者能夠即時交流和交換訊息,不受地理和時區限制。聊天室的實作方式多種多樣,本文將介紹如何用nodejs搭建一個聊天室。

一、聊天室的基本實作原理

聊天室是基於網路的即時通訊系統,其實作原理非常簡單。當使用者進入聊天室時,使用者需先連線到聊天伺服器,伺服器會將使用者的連線資訊加入聊天室的使用者清單。當用戶向聊天室發送訊息時,伺服器會將訊息廣播給所有在聊天室中的用戶。此外,伺服器還需要即時監測用戶的連線狀態和斷開連線的用戶資訊。

二、準備工作

在開始建立聊天室之前,請確保您已經安裝了nodejs和npm,如果沒有安裝,可以前往nodejs官網下載安裝。

三、建置聊天室的伺服器端

  1. 建立專案

#首先,我們需要在本地環境下建立一個聊天室的項目,並下載一些必要的模組。在命令列中先建立一個專案目錄並進入:

mkdir myChatRoom
cd myChatRoom

然後使用npm初始化專案:

npm init

接下來安裝需要使用的模組:

npm i express socket.io -S

在以上命令中:

  • express是一個常用的nodejs web框架,用來處理HTTP請求和回應。
  • socket.io是一個基於websocket封裝的即時通訊庫。
  1. 服務端程式碼實作

在專案根目錄下,建立index.js文件,並將以下程式碼貼入:

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

app.use(express.static(__dirname + '/public'));

const onlineUsers = {};
const onlineCount = 0;

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

  socket.on('login', (user) => {
    socket.nickname = user.username;
    // check if the user already exists
    if (!onlineUsers.hasOwnProperty(socket.nickname)) {
      onlineUsers[socket.nickname] = user.avatar;
      onlineCount++;
    }

    io.emit('login', { onlineUsers, onlineCount, user });
    console.log(`user ${user.username} joined`);
  });

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

  socket.on('disconnect', () => {
    if (onlineUsers.hasOwnProperty(socket.nickname)) {
      const userLeft = { username: socket.nickname, avatar: onlineUsers[socket.nickname] };
      delete onlineUsers[socket.nickname];
      onlineCount--;

      io.emit('logout', { onlineUsers, onlineCount, user: userLeft });
      console.log(`user ${userLeft.username} left`);
    }
  });
});

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

以上程式碼中,我們啟動了一個http伺服器,並且使用socket.io對HTTP服務進行了升級,以支援websocket。然後我們可以看到我們定義了幾個socket事件:

  1. 當有新的Socket連線時,伺服器會傳送connection事件,我們會輸出「a user connected」。
  2. 當使用者登入時,伺服器會傳送login事件,並將該使用者的資訊加入線上使用者清單中,然後伺服器會將線上使用者清單廣播給其他使用者。
  3. 當使用者傳送訊息時,伺服器會傳送chatMessage事件,並將訊息廣播給所有線上使用者。
  4. 當有使用者中斷連線時,伺服器會傳送disconnect事件,並將該使用者從線上使用者清單中刪除。

四、搭建聊天室客戶端

  1. 建立html文件

在專案的public目錄下,建立一個html文件,並且將下面的程式碼拷貝入文件中:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Chatroom</title>
    <style>
        #nickname {
            display: none;
        }

        #messages {
            height: 300px;
            overflow-y: scroll;
            margin-bottom: 10px;
        }

        ul {
            list-style: none;
            padding: 0;
            margin: 0;
        }

        li {
            margin-top: 10px;
        }

        img {
            width: 30px;
            height: 30px;
            vertical-align: middle;
            margin-right: 10px;
        }
    </style>
</head>
<body>
<div id="loginPanel">
    <p>输入一个昵称:</p>
    <input type="text" id="nicknameInput">
    <button id="submit">进入聊天室</button>
</div>
<div id="chatroom" style="display:none;">
    <div id="nickWrapper">
        <img id="avatarImg" src=""/>
        <span id="nickname"></span>
        <button id="logout">退出聊天室</button>
    </div>
    <div id="messages"></div>
    <input type="text" id="messageInput" placeholder="请输入聊天信息">
    <button id="sendBtn">发送</button>
</div>

<script src="./socket.io/socket.io.js"></script>
<script src="./chat.js"></script>
</body>
</html>

以上程式碼中,我們為HTML 添加了一個暱稱輸入框,一個進入聊天室的按鈕,一個退出聊天室的按鈕,一個ID 為“messages”的元素,一個發送訊息的輸入框和一個發送訊息的按鈕。其中,暱稱輸入框和進入聊天室的按鈕在進入聊天室後就被隱藏了,顯示的是線上用戶的暱稱和頭像。

  1. 建立聊天室用戶端JS程式碼

在public目錄下建立一個chat.js文件,將下面的程式碼貼入其中:

const socket = io();
const submitBtn = document.querySelector('#submit');
const logoutBtn = document.querySelector('#logout');
const sendBtn = document.querySelector('#sendBtn');
const messageInput = document.querySelector('#messageInput');
const nicknameInput = document.querySelector('#nicknameInput');
const chatWrapper = document.querySelector('#chatroom');
const loginPanel = document.querySelector('#loginPanel');
const avatarImg = document.querySelector('#avatarImg');
const nickname = document.querySelector('#nickname');
const messages = document.querySelector('#messages');

let avatar;


// 提交昵称登录
submitBtn.addEventListener('click', function () {
  const nickname = nicknameInput.value;
  if (nickname.trim().length > 0) {
    avatar = `https://avatars.dicebear.com/api/bottts/${Date.now()}.svg`;
    socket.emit('login', { username: nickname, avatar: avatar });
  } else {
    alert('昵称为空,请重新输入');
    nicknameInput.value = '';
    nicknameInput.focus();
  }
});

// 退出登录
logoutBtn.addEventListener('click', function () {
  socket.disconnect();
});

// 发送消息
sendBtn.addEventListener('click', function () {
  const msg = messageInput.value.trim();
  if (msg.length > 0) {
    socket.emit('chatMessage', msg);
    messageInput.value = '';
    messageInput.focus();
  }
});

// 回车发送消息
messageInput.addEventListener('keyup', function (e) {
  e.preventDefault();
  if (e.keyCode === 13) {
    sendBtn.click();
  }
});

// 服务器发送登录信号
socket.on('login', (info) => {
  loginPanel.style.display = 'none';
  chatWrapper.style.display = 'block';
  avatarImg.src = avatar;
  nickname.innerText = nicknameInput.value;
  renderUserList(info.onlineUsers);
});

// 服务器发送聊天消息信号
socket.on('chatMessage', (data) => {
  renderChatMessage(data.nickname, data.message);
});

// 服务器发送退出信号
socket.on('logout', (info) => {
  renderUserList(info.onlineUsers);
});

// 渲染在线用户列表
function renderUserList(users) {
  const list = document.createElement('ul');
  Object.keys(users).forEach((nickname) => {
    const item = `
    <li>
      <img src="${users[nickname]}"/>
      <span>${nickname}</span>
    </li>
    `;
    list.innerHTML += item;
  });
  chatWrapper.insertBefore(list, messages);
}

// 渲染聊天消息
function renderChatMessage(nickname, message) {
  const msg = document.createElement('div');
  msg.innerHTML = `<p>${nickname}: ${message}</p>`;
  messages.appendChild(msg);
}

以上程式碼中,我們實現了以下功能:

  1. 當用戶點擊“登入”按鈕時,向伺服器發送“login”事件,委託伺服器在其內部將用戶新增至“線上用戶”清單中,並透過廣播將目前「線上使用者」清單推送給所有客戶端。
  2. 當有聊天訊息時,伺服器將發送「chatMessage」事件,並透過廣播將訊息的內容推送給所有客戶端。
  3. 當有使用者斷開連線時,「線上使用者清單」會將該使用者從使用者清單中刪除,並透過廣播將目前「線上使用者」清單推送給所有客戶端。

五、執行專案

在命令列進入到專案根目錄下,輸入以下命令啟動專案:

node index.js

接著在瀏覽器中輸入http ://localhost:3000/ 存取伺服器,進入聊天室。

六、總結

在這篇文章中,我們實作了一個簡單的聊天室,基於nodejs和socket.io,為聊天室的搭建提供了一種簡單、穩定和高效的方式。雖然這只是一個非常基礎的聊天室,但是相信讀者透過這篇文章的介紹和實踐,能夠對nodejs搭建聊天室有一個大致的認識和了解。

以上是用nodejs搭建聊天室的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn