首页 web前端 前端问答 用nodejs搭建聊天室

用nodejs搭建聊天室

May 24, 2023 pm 12:23 PM

随着互联网的飞速发展,人们之间的交流方式也在不断改变。聊天室是一种在线的即时通讯应用,它让用户能够实时交流和交换信息,不受地域和时区限制。聊天室的实现方式多种多样,本文将介绍如何用nodejs搭建一个聊天室。

一、聊天室的基本实现原理

聊天室是基于网络的即时通讯系统,其实现原理非常简单。当用户进入聊天室时,用户需先连接到聊天服务器,服务器会将用户的连接信息加入到聊天室的用户列表中。当用户向聊天室发送消息时,服务器会将消息广播给所有在聊天室中的用户。此外,服务器还需要实时监测用户的连接状态和断开连接的用户信息。

二、准备工作

在开始建立聊天室之前,要确保您已经安装了nodejs和npm,如果没有安装,可以前往nodejs官网下载安装。

三、搭建聊天室的服务器端

  1. 创建项目

首先,我们需要在本地环境下创建一个聊天室的项目,并下载一些必要的模块。在命令行中先创建一个项目目录并进入:

1

2

mkdir myChatRoom

cd myChatRoom

登录后复制

然后使用npm初始化项目:

1

npm init

登录后复制

接下来安装需要使用的模块:

1

npm i express socket.io -S

登录后复制

以上命令中:

  • express是一个常用的nodejs web框架,用来处理HTTP请求和响应。
  • socket.io是一个基于websocket封装的实时通信库。
  1. 服务端代码实现

在项目根目录下,创建index.js文件,并将以下代码贴入:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

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文件,并且将下面的代码拷贝入文件中:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

<!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文件,将下面的代码贴入其中:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

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. 当有用户断开连接时,“在线用户列表”会将该用户从用户列表中删除,并通过广播将当前“在线用户”列表推送给所有客户端。

五、运行项目

在命令行中进入到项目根目录下,输入以下命令启动项目:

1

node index.js

登录后复制

接着在浏览器中输入http://localhost:3000/ 访问服务器,进入聊天室。

六、总结

在这篇文章中,我们实现了一个简单的聊天室,基于nodejs和socket.io,为聊天室的搭建提供了一种简单、稳定和高效的方式。虽然这只是一个非常基础的聊天室,但是相信读者通过这篇文章的介绍和实践,能够对nodejs搭建聊天室有一个大概的认识和了解。

以上是用nodejs搭建聊天室的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
威尔R.E.P.O.有交叉游戏吗?
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

什么是使用效果?您如何使用它执行副作用? 什么是使用效果?您如何使用它执行副作用? Mar 19, 2025 pm 03:58 PM

本文讨论了React中的使用效应,这是一种用于管理副作用的钩子,例如数据获取和功能组件中的DOM操纵。它解释了用法,常见的副作用和清理,以防止记忆泄漏等问题。

反应和解算法如何起作用? 反应和解算法如何起作用? Mar 18, 2025 pm 01:58 PM

本文解释了React的对帐算法,该算法通过比较虚拟DOM树有效地更新DOM。它讨论了性能优势,优化技术以及对用户体验的影响。

JavaScript中的高阶功能是什么?如何使用它们来编写更简洁和可重复使用的代码? JavaScript中的高阶功能是什么?如何使用它们来编写更简洁和可重复使用的代码? Mar 18, 2025 pm 01:44 PM

JavaScript中的高阶功能通过抽象,常见模式和优化技术增强代码简洁性,可重复性,模块化和性能。

咖喱如何在JavaScript中起作用,其好处是什么? 咖喱如何在JavaScript中起作用,其好处是什么? Mar 18, 2025 pm 01:45 PM

本文讨论了JavaScript中的咖喱,这是一种将多重题材函数转换为单词汇函数序列的技术。它探讨了咖喱的实施,诸如部分应用和实际用途之类的好处,增强代码阅读

如何使用Connect()将React组件连接到Redux Store? 如何使用Connect()将React组件连接到Redux Store? Mar 21, 2025 pm 06:23 PM

文章讨论了使用Connect()将React组件连接到Redux Store,解释了MapStateToprops,MapDispatchToprops和性能影响。

什么是Usecontext?您如何使用它在组件之间共享状态? 什么是Usecontext?您如何使用它在组件之间共享状态? Mar 19, 2025 pm 03:59 PM

本文解释了React中的UseContext,该文章通过避免道具钻探简化了状态管理。它讨论了通过减少的重新租赁者进行集中国家和绩效改善之类的好处。

您如何防止事件处理程序中的默认行为? 您如何防止事件处理程序中的默认行为? Mar 19, 2025 pm 04:10 PM

文章讨论了使用DestrestDefault()方法在事件处理程序中预防默认行为,其好处(例如增强的用户体验)以及诸如可访问性问题之类的潜在问题。

您如何在React中实现自定义挂钩? 您如何在React中实现自定义挂钩? Mar 18, 2025 pm 02:00 PM

本文讨论了在React中实施自定义钩子,重点是他们的创建,最佳实践,绩效好处和避免常见的陷阱。

See all articles