WebSocket 详解:构建一个复杂的实时聊天应用

文章目录

  • 一、前言
  • 二、WebSocket 基础
    • 2.1 WebSocket 与 HTTP 的区别
    • 2.2 WebSocket 的优点
  • 三、搭建 WebSocket 服务端
    • 3.1 安装 `ws` 和 `redis` 库
    • 3.2 创建 WebSocket 服务端
    • 3.3 创建用户身份验证
  • 四、前端实现 WebSocket 客户端
    • 4.1 创建 Vue 3 项目
    • 4.2 实现 WebSocket 连接和用户注册
  • 五、WebSocket 安全性与优化
    • 5.1 消息加密
    • 5.2 连接池与负载均衡

一、前言

在实时应用的开发中,WebSocket 已经成为实现高效、低延迟实时通讯的关键技术。通过建立持久的双向连接,WebSocket 不仅可以减少网络请求的开销,还能支持高效的数据传输。在本教程中,我们将创建一个更复杂的聊天应用,除了实现基本的 WebSocket 连接外,还将扩展一些常见的应用场景:私聊、群聊、消息持久化、用户身份验证等。

二、WebSocket 基础

2.1 WebSocket 与 HTTP 的区别

  • HTTP 协议:每次客户端请求时,都会重新建立连接,适用于请求-响应模式。
  • WebSocket 协议:创建一个持久连接,支持全双工通信,使得数据传输更高效。客户端和服务器之间能够实时发送和接收数据。

2.2 WebSocket 的优点

  • 低延迟:通过持久连接,避免了频繁的请求和响应开销。
  • 双向通信:客户端和服务器可以实时交换数据。
  • 减少带宽消耗:长期保持一个连接,不再需要重新建立连接。

三、搭建 WebSocket 服务端

我们将使用 Node.jsws 库创建 WebSocket 服务器,并通过 Redis 实现群聊的消息广播。

3.1 安装 wsredis

首先,创建 Node.js 项目并安装所需的依赖:

npm init -y
npm install ws redis

3.2 创建 WebSocket 服务端

server.js 中,我们将实现一个 WebSocket 服务器,支持群聊和私聊功能。

// server.js
const WebSocket = require('ws');
const redis = require('redis');// 创建 WebSocket 服务器,监听端口 8080
const wss = new WebSocket.Server({ port: 8080 });// 连接 Redis 客户端
const client = redis.createClient();// 存储所有连接的 WebSocket 客户端
let users = {};wss.on('connection', ws => {console.log('客户端已连接');// 处理消息接收ws.on('message', (message) => {const data = JSON.parse(message);const { type, user, content, target } = data;if (type === 'chat') {// 广播消息到所有客户端(群聊)broadcast(user, content);} else if (type === 'private') {// 私聊消息(发送到指定目标)privateMessage(user, target, content);} else if (type === 'history') {// 请求聊天记录getHistory(ws);}});// 连接成功时,给客户端一个欢迎消息ws.on('open', () => {ws.send(JSON.stringify({ user: 'server', content: '欢迎来到聊天室!' }));});// 监听客户端断开连接ws.on('close', () => {console.log('客户端已断开连接');// 用户断开连接后,清理用户信息Object.keys(users).forEach((key) => {if (users[key] === ws) {delete users[key];}});});// 广播消息到所有客户端function broadcast(user, content) {wss.clients.forEach(client => {if (client.readyState === WebSocket.OPEN) {client.send(JSON.stringify({ user, content }));}});// 将聊天记录保存到 Redis 中client.rpush('chatHistory', JSON.stringify({ user, content }));}// 私聊功能:发送消息给特定的用户function privateMessage(user, target, content) {const targetSocket = users[target];if (targetSocket) {targetSocket.send(JSON.stringify({ user, content }));} else {ws.send(JSON.stringify({ user: 'server', content: '用户不在线' }));}}// 获取历史聊天记录function getHistory(ws) {client.lrange('chatHistory', 0, -1, (err, messages) => {if (err) {ws.send(JSON.stringify({ user: 'server', content: '获取聊天记录失败' }));} else {ws.send(JSON.stringify({ user: 'server', content: messages }));}});}// 注册用户ws.on('message', (data) => {const message = JSON.parse(data);if (message.type === 'register') {users[message.user] = ws;console.log(`${message.user} 已注册`);}});
});

3.3 创建用户身份验证

为了实现用户身份验证,我们可以通过 WebSocket 连接时传递一个 token,来验证用户的身份。

// 用户身份验证
ws.on('connection', (socket, request) => {const token = request.url.split('token=')[1]; // 从 URL 中获取 tokenif (isValidToken(token)) {// 如果 token 验证通过,继续连接socket.send('身份验证通过');} else {socket.close(); // 否则关闭连接}
});

四、前端实现 WebSocket 客户端

我们将使用 Vue 3 创建聊天应用,并实现消息发送、接收、私聊等功能。

4.1 创建 Vue 3 项目

通过 Vue CLI 创建一个新的 Vue 项目:

vue create websocket-chat

4.2 实现 WebSocket 连接和用户注册

ChatRoom.vue 中实现 WebSocket 客户端:

<template><div class="chat-room"><div class="messages"><div v-for="(message, index) in messages" :key="index" class="message"><strong>{{ message.user }}:</strong> {{ message.content }}</div></div><input v-model="newMessage" @keyup.enter="sendMessage" placeholder="Type a message..." /><button @click="sendPrivateMessage">私聊</button></div>
</template><script>
export default {data() {return {socket: null,messages: [],newMessage: '',user: 'User' + Math.floor(Math.random() * 1000),targetUser: '', // 私聊目标用户};},mounted() {this.socket = new WebSocket('ws://localhost:8080');this.socket.onopen = () => {this.socket.send(JSON.stringify({ type: 'register', user: this.user }));};this.socket.onmessage = (event) => {const message = JSON.parse(event.data);this.messages.push(message);this.scrollToBottom();};},methods: {sendMessage() {if (this.newMessage.trim()) {this.socket.send(JSON.stringify({ type: 'chat', user: this.user, content: this.newMessage }));this.newMessage = '';}},sendPrivateMessage() {if (this.targetUser && this.newMessage.trim()) {this.socket.send(JSON.stringify({type: 'private',user: this.user,target: this.targetUser,content: this.newMessage,}));this.newMessage = '';}},scrollToBottom() {const container = this.$refs.messageContainer;container.scrollTop = container.scrollHeight;},},
};
</script>

五、WebSocket 安全性与优化

5.1 消息加密

为了保障通信安全,可以使用 AES 加密协议加密传输的消息内容,确保数据在传输过程中不会被窃取。

5.2 连接池与负载均衡

当 WebSocket 服务器需要处理大量连接时,可以使用连接池和负载均衡技术。例如,使用 Nginx 配置 WebSocket 反向代理。


到这里,这篇文章就和大家说再见啦!我的主页里还藏着很多 篇 前端 实战干货,感兴趣的话可以点击头像看看,说不定能找到你需要的解决方案~
创作这篇内容花了很多的功夫。如果它帮你解决了问题,或者带来了启发,欢迎:
点个赞❤️ 让更多人看到优质内容
关注「前端极客探险家」🚀 每周解锁新技巧
收藏文章⭐️ 方便随时查阅
📢 特别提醒:
转载请注明原文链接,商业合作请私信联系
感谢你的阅读!我们下篇文章再见~ 💕

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/76753.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【JavaEE进阶】Spring AOP入门

欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗 如有错误&#xff0c;欢迎指出~ AOP是Spring框架的第⼆⼤核⼼(第⼀⼤核⼼是 IoC) 什么是AOP&#xff1f; • AspectOrientedProgramming&#xff08;⾯向切⾯编程&#xff09; 什么是⾯向切⾯编程呢? 切…

算法思想之双指针(一)

欢迎拜访&#xff1a;雾里看山-CSDN博客 本篇主题&#xff1a;算法思想之双指针(一) 发布时间&#xff1a;2025.4.4 隶属专栏&#xff1a;算法 目录 双指针算法介绍对撞指针&#xff1a;快慢指针&#xff1a; 例题移动零题目链接题目描述算法思路代码实现 复写零题目链接题目描…

【11408学习记录】英语写作黄金模板+语法全解:用FTC数据泄漏案掌握书信结构与长难句拆解(附思维导图)

2025.04.04 英语写作书信写作第一段私人信件公务信函 语法总结——简单句简单句的核心&#xff1a;谓语动词的变化词性的拓展限定词 形容词与副词介词短语 成分的扩展同位语插入语 非谓语动词 每日一句词汇 第一步&#xff1a;辨别第二步&#xff1a;断开第三步&#xff1a;简化…

手机显示5GA图标的条件

最近有星友问在什么情况下才能显示5G-A&#xff1f;虽然这个我也不知道&#xff0c;但是我有几个运营商的5G终端白皮书&#xff0c;从上面就可以找到答案。 如上是几个运营商显示5G-A的条件&#xff0c;基本上考虑的都是3CC的情况&#xff0c;联通还有考虑200M CA 2CC的场景&am…

网络:华为数通HCIA学习:IP路由基础

华为HCIA学习 IP路由基础路由协议或路由种类以及对应路由的优先级按工作区域分类&#xff1a;按工作机制及算法分类&#xff1a;路由的优先级路由器选择最优路由的顺序是什么? 前言自治系统LAN和广播域路由选路IP路由表路由度量建立路由表最长匹配原则路由器转发数据包总结 IP…

Docker 镜像相关的基本操作

一、Docker 镜像基本操作 1. 查找镜像 命令&#xff1a; docker search <镜像名称> 示例&#xff1a;查找 CentOS 镜像&#xff1a; docker search centos 命令解释&#xff1a; 默认从 Docker Hub 官方仓库上搜索镜像。搜索结果包含多个列&#xff1a; NAME&…

Linux文件特殊权限管理及进程和线程

acl 权限优先级 拥有者 > 特殊指定用户 > 权限多的组 >权限少的组 > 其他 mask阈值 mask是能够赋予指定用户权限的最大阀值 当设定完毕文件的acl列表之后用chmod缩小了文件拥有组的权力 mask会发生变化 恢复&#xff1a; setfacl -m m: 权限 :rwx 文件/…

NVIDIA AgentIQ 详细介绍

NVIDIA AgentIQ 详细介绍 1. 引言 NVIDIA AgentIQ 是一个灵活的库&#xff0c;旨在将企业代理&#xff08;无论使用何种框架&#xff09;与各种数据源和工具无缝集成。通过将代理、工具和代理工作流视为简单的函数调用&#xff0c;AgentIQ 实现了真正的可组合性&#xff1a;一…

算法设计与分析5(动态规划)

动态规划的基本思想 将一个问题划分为多个不独立的子问题&#xff0c;这些子问题在求解过程中可能会有些数据进行了重复计算。我们可以把计算过的数据保存起来&#xff0c;当下次遇到同样的数据计算时&#xff0c;就可以查表直接得到答案&#xff0c;而不是再次计算 动态规划…

怎么理解量子比特模型,迁移到量子计算机开始编程

怎么理解量子比特模型&#xff0c;迁移到量子计算机开始编程 视频链接&#xff1a; 好的现在是2025年的3月最后一天,3月31号,今天我们讨论的话题是量子编程,也就是在量子计算机上,使用特定的语言进行软件开发。当然我们要讨论的,不是,量子编程的某一门语言的技术细节,而是考虑…

使用Expo框架开发APP——详细教程

在移动应用开发日益普及的今天&#xff0c;跨平台开发工具越来越受到开发者青睐。Expo 是基于 React Native 的一整套工具和服务&#xff0c;它能够大幅降低原生开发的门槛&#xff0c;让开发者只需关注业务逻辑和界面实现&#xff0c;而不用纠结于复杂的原生配置。本文将从零开…

windows技术基础知识

NT架构 NT 就是new techonology 的英文单词缩写&#xff0c;是微软1993年推出操作系统的重大升级&#xff0c;如内存管理&#xff0c;安全机制&#xff0c;多任务&#xff0c;多线程支持。在此之前操作系统都是基于MS-DOS上面的图形化界面&#xff0c;只有有限的内存管理和多任…

迪杰斯特拉+二分+优先队列+拓扑+堆优化(奶牛航线Cowroute、架设电话线dd、路障Roadblocks、奶牛交通Traffic)

原文地址 https://fmcraft.top/index.php/Programming/2025040402.html 主要算法 迪杰斯特拉Dijkstra 题目列表 P1&#xff1a;奶牛航线Cowroute 题目描述 题目描述 Bessie已经厌倦了农场冬天的寒冷气候&#xff0c;她决定坐飞机去更温暖的地方去度假。不幸的是&#xf…

#Liunx内存管理# 在32bit Linux内核中,用户空间和内核空间的比例通常是3:1,可以修改成2:2吗?

在32位Linux内核中&#xff0c;用户空间和内核空间的3:1默认比例可以修改为2:2&#xff0c;但需要权衡实际需求和潜在影响。以下是具体分析&#xff1a; 一、修改可行性 1.技术实现 通过内核启动参数调整虚拟地址空间划分&#xff0c;例如在GRUB配置中添加mem2G参数&#xff0c…

JAVA:使用 Curator 进行 ZooKeeper 操作的技术指南

1、简述 Apache Curator 是一个基于 ZooKeeper 的 Java 客户端库&#xff0c;它极大地简化了使用 ZooKeeper 的开发工作。Curator 提供了高层次的 API&#xff0c;封装了很多复杂的 ZooKeeper 操作&#xff0c;例如连接管理、分布式锁、Leader 选举等。 在分布式系统中&#…

Julia语言的测试覆盖率

Julia语言的测试覆盖率探讨 引言 在现代软件开发中&#xff0c;测试是确保软件质量的重要环节。随着软件的复杂度不断增加&#xff0c;测试覆盖率作为衡量测试质量的一个重要指标&#xff0c;受到了越来越多开发者的关注。Julia语言作为一种高性能的动态编程语言&#xff0c;…

【万字总结】前端全方位性能优化指南(八)——Webpack 6调优、模块联邦升级、Tree Shaking突破

构建工具深度优化——从机械配置到智能工程革命 当Webpack配置项突破2000行、Node进程内存耗尽告警时,传统构建优化已触及工具链的物理极限:Babel转译耗时占比超60%、跨项目模块复用催生冗余构建、Tree Shaking误删关键代码引发线上事故……构建流程正从「工程问题」演变为「…

使用MCP服务器实现AI任务完成通知:让Cursor更智能

0. 简介 在使用AI工具进行长时间任务时&#xff0c;常常需要等待结果。MCP&#xff08;Model Context Protocol&#xff09;服务器"mcp_server_notify"提供了一个优雅的解决方案&#xff0c;让AI在完成任务后通过系统通知提醒你。本文将介绍如何在Cursor中配置和使用…

Java面试黄金宝典33

1. 什么是存取控制、 触发器、 存储过程 、 游标 存取控制 定义&#xff1a;存取控制是数据库管理系统&#xff08;DBMS&#xff09;为保障数据安全性与完整性&#xff0c;对不同用户访问数据库对象&#xff08;如表、视图等&#xff09;的权限加以管理的机制。它借助定义用户…

DataX实战教程

需求&#xff1a; 用datax同步mysql&#xff1a; 192.168.236.134中test1库的user表到192.168.236.136中test1库的user表 步骤&#xff1a; 下载安装包 https://github.com/alibaba/DataX/blob/master/userGuid.md 进入引导页 https://github.com/alibaba/DataX/blob/ma…