使用 Socket.io + JavaScript 进行简单的即时聊天(一)

我开始这个项目是因为我有兴趣学习如何使用 websockets。我还找到了各种后台模板,但没有一个能满足我的要求。所以我决定研究如何创建一个简单的即时聊天后台。我测试了两种方案:第一种是使用 Socket.io 和 Node.js,第二种是使用 Socket.io 和 MongoDB 来存储消息历史记录。本文将讨论第一种方案。

前端

首先创建了一个简单的 “登录 “页面,供用户输入用户名并加入聊天。具体步骤如下:

1. 创建一个 “client”文件夹,在 VSCode 中打开它,然后在 client 文件夹中运行 npm init 命令来初始化项目。

2. 创建一个 “index.html “文件。

3. 在 “package.json “中添加以下命令以启动项目:

“scripts”: {
  "run": "index.html"
}

4. 创建 “style.css “和 “main.js”。为了节省时间,我使用了 Bootstrap 来创建样式。

5. 将文件链接到 “index.html “文件,并包含 Bootstrap。

6. 为登录页面创建 HTML 结构:

<div id="login-container" class="container justify-content-center align-items-center">
  <div class="login-wrapper w-100">
    <form id="login" class="d-flex flex-column align-items-center w-100">
      <h2 class="hedline-login">Log In to Chat</h2>
      <input id="username" class="form-control w-50" type="text">
      <button class="btn btn-outline-info btn-lg w-50" type="submit">Log In</button>
    </form>
  </div>
</div>

聊天页面

<div id="chat-container" class="container hidden">
  <div class="wrapper d-flex flex-column justify-content-between w-100">
  <ul id="message-container">
  </ul>

  <form class="message-form__container d-flex align-items-center w-100" id="message-form" action="" method="">
    <textarea class="textarea-form" id="message-input" cols="2" rows="3"></textarea>
    <button class="btn btn-outline-info btn-lg" type="submit">Send</button>
  </form>
  </div>
</div>

7. 在 “index.html “文件中链接 Socket.io 库:

<script src=”http://localhost:5000/socket.io/socket.io.js"></script>

JavaScript 代码:

1. 使用服务器 URL 初始化 Socket.io:

const socket = io (' http : //localhost:5000');

2. 获取登录表单、消息输入、消息容器以及登录和聊天容器的元素:

const messageContainer = document.getElementById(‘message-container’);
const messageForm = document.getElementById(‘message-form’);
const messageInput = document.getElementById(‘message-input’);
const loginContainer = document.getElementById(‘login-container’);
const chatContainer = document.getElementById(‘chat-container’);
const loginFrom = document.getElementById(‘login’);
const usernameEl = document.getElementById(‘username’);
let username = ‘’;

3. 为来自用户和系统的信息定义类别:

const msgFromMeClass = 'message - from-me';
const msgSystemClass = 'message - system';

4. 设置事件监听器,处理用户登录时提交的表单:

loginFrom.addEventListener('submit', e =>{
});

5. 阻止默认表单提交行为:

loginFrom.addEventListener('submit', e =>{
  e.preventDefault();
});

6. 从输入框中获取用户名:

loginFrom.addEventListener('submit', e =>{
  e.preventDefault();
  username = usernameEl.value;
});

7. 发出“new-user”事件以通知服务器有关新用户的信息:

loginFrom.addEventListener('submit', e =>{
  e.preventDefault();
  username = usernameEl.value;
  socket.emit('new-user', username);
});

8. 更新显示状态,从登录状态切换到聊天状态:

在 style.css 中创建了一个类,名为 “hidden”,内含 “display: none;”。

loginFrom.addEventListener('submit', e =>{
  e.preventDefault();
  username = usernameEl.value;
  socket.emit('new-user', username);
  loginContainer.classList.add('hidden');
  chatContainer.classList.remove('hidden');
});

9. 处理“user-connected”事件,通知其他用户新用户的连接情况:

loginFrom.addEventListener('submit', e =>{
  e.preventDefault();
  username = usernameEl.value;
  socket.emit('new-user', username);
  loginContainer.classList.add('hidden');
  chatContainer.classList.remove('hidden');
    socket.on('user-connected', user => {
  });
});

10. 创建渲染聊天消息和系统消息的函数:

function renderMessage(from, message, className){
  messageContainer.innerHTML += `
  <li class="${className}">
    <div class="message">
      <span class="author" style="font-size: 70%;">${from}</span>
      <span class="message-text">${message}</span>
    </div>
  </li>
  `;
}

11. 监听传入的聊天信息,并使用渲染功能显示它们:

因此,我将其称为 “from”,即我们的消息正文。它可以是来自用户的消息,也可以是系统消息,如 “用户名已连接”。

className:设置来自我和用户的消息的样式。

12. 置使用“Enter”键或单击按钮发送聊天消息的处理程序:

messageForm.addEventListener('submit', handleSubmit);
messageInput.addEventListener('keydown', handleSubmit);

function handleSubmit(e) {
  if (e.key === 'Enter' || e.type === 'submit') {
    e.preventDefault();
    const message = messageInput.value;
    if (!message.trim()) return;
    socket.emit('send-chat-message', message);
    messageInput.value = '';
  }
}

13. 包含基本验证以防止发送空消息:

if (!message.trim ( )) return ;

14. 向服务器发出“send-chat-message”事件:

socket.emit('send-chat-message', message);

15. 处理“chat-message”事件以显示传入的聊天消息:

socket.on('chat-message', data => {
  const addingClass = username === data.username ? msgFromMeClass : '';
  renderMessage(data.username, data.message, addingClass);
});

16. 收到新消息时,在聊天容器中添加自动滚动功能:

messageContainer.scrollTop = messageContainer.scrollHeight;

完整代码:

function renderMessage(from, message, className){
  messageContainer.innerHTML += `
  <li class="${className}">
    <div class="message">
      <span class="author" style="font-size: 70%;">${from}</span>
      <span class="message-text">${message}</span>
    </div>
  </li>
  `;
  messageContainer.scrollTop = messageContainer.scrollHeight;
}

17. 以相同的方式创建断开连接:

socket.on('user-disconnected', username => {
  renderMessage('SYSTEM', `${username} disconnected`, msgSystemClass)
});

后台

1. 创建 “服务器 “文件夹。

2. 使用 npm init 初始化项目。

3. 创建一个 “index.js “文件。

4. 安装 Socket.io 和 Express.js 软件包:

npm install socket.io 
npm install express

5. 导入Socket.io模块:

import { Server } from 'socket.io';

6. 创建一个对象来存储用户数据:

const users = {};

7. 设置 CORS(跨来源资源共享),允许所有来源:

npm install cors

8. 创建 Socket.IO 服务器并将其绑定到 5000 端口:

const io = new Server(5000, {
  cors: {
    origin: '*',
  }
});

9. 处理用户连接:

io.on('connection', (socket) => {
  socket.on('new-user', username => {
    users[socket.id] = username;
    socket.emit('user-connected', username);
    socket.broadcast.emit('user-connected', username);
  });
});

10. 发布事件,通知用户新连接、断开连接和聊天信息:

socket.on('send-chat-message', (message) => {
  socket.emit('chat-message', { message: message, username: users[socket.id] })
  socket.broadcast.emit('chat-message', { message: message, username: users[socket.id] })
  });

  socket.on('disconnect', () => {
  socket.broadcast.emit('user-disconnected', users[socket.id])
  delete users[socket.id]
});

此代码的完整版本如下所示

io.on('connection', (socket) => {
  socket.on('new-user', username => {
    users[socket.id] = username;
    socket.emit('user-connected', username);
    socket.broadcast.emit('user-connected', username);
  });

  socket.on('send-chat-message', (message) => {
    socket.emit('chat-message', { message: message, username: users[socket.id] })
    socket.broadcast.emit('chat-message', { message: message, username: users[socket.id] })
  });

  socket.on('disconnect', () => {
    socket.broadcast.emit('user-disconnected', users[socket.id])
    delete users[socket.id]
  });
});

最后为 HTML 元素应用样式。源代码地址:https://github.com/soyUnaGata/real-time-chat.git

使用 Socket.io + JavaScript 进行简单的即时聊天(一)

使用 MongoDB 的第二部分即将推出。

作者:unaGataProgrammer

本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/im/37544.html

(0)

相关推荐

发表回复

登录后才能评论