当前位置 : 主页 > 网页制作 > HTTP/TCP >

用nodejs搭建聊天室

来源:互联网 收集:自由互联 发布时间:2023-08-07
随着互联网的飞速发展,人们之间的交流方式也在不断改变。聊天室是一种在线的即时通讯应用,它让用户能够实时交流和交换信息,不受地域和时区限制。聊天室的实现方式多种多样

随着互联网的飞速发展,人们之间的交流方式也在不断改变。聊天室是一种在线的即时通讯应用,它让用户能够实时交流和交换信息,不受地域和时区限制。聊天室的实现方式多种多样,本文将介绍如何用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判断端口是否占用
下一篇:没有了
网友评论