当前位置: 首页 > news >正文

【11/20】实时数据基础:WebSocket 在 Express 和 Vue 中的整合,实现简单聊天功能

标签:实时数据、WebSocket、Socket.io、Express、Vue.js、聊天功能、入门教程、项目实践

前言

欢迎来到“前后端与数据库交互详解”系列的第11篇文章!在前十篇文章中,我们从Vue.js前端基础,到Express后端、MongoDB整合、JWT认证,再到Vuex状态管理,构建了一个带认证和全局状态的用户管理系统。现在,应用已有CRUD和认证,但缺乏实时交互,如即时消息。

本篇文章的焦点是 实时数据基础,特别是用WebSocket在Express和Vue中整合,实现简单聊天功能。我们将解释WebSocket是什么、如何与HTTP不同,并在结尾扩展第十篇的项目:添加实时聊天室组件,只有认证用户可加入,消息通过WebSocket广播,并用Vuex管理聊天状态。这将形成一个更互动的full-stack应用。未来,我们将深入数据库高级查询。

前提:您已安装Node.js和Vue CLI(前文)。安装Socket.io:后端npm install socket.io,前端npm install socket.io-client。后端基于第八篇运行;前端用第十篇的Vuex和路由。

一、实时数据是什么?

实时数据是通过双向、持久连接(如WebSocket)实现即时通信的机制,而非HTTP的请求-响应模型。

  • 为什么需要WebSocket?

    • 实时性:适合聊天、通知、协作;HTTP轮询低效(高延迟/负载)。
    • WebSocket 优势:全双工(服务器/客户端互推),低开销,支持二进制。
    • 对比其他:SSE(单向推送);我们用Socket.io(WebSocket封装,支持事件、房间、回退到长轮询)。
    • 安全考虑:验证连接(整合JWT);避免DDoS,用rate limiting。
    • 在full-stack中的作用:后端监听事件,前端emit/receive,结合Vuex更新UI。
    • 与认证整合:连接时发送JWT,服务器验证。
  • 核心概念

    • 连接:客户端io.connect(url),服务器io.on(‘connection’)。
    • 事件:emit(‘message’, data)发送,on(‘message’, callback)接收。
    • 房间:io.to(‘room’).emit广播特定组。
    • 断开:处理disconnect事件。
    • 在Vue中的作用:组件mounted时连接,更新state显示消息。

在我们的系列中,WebSocket添加实时聊天到用户系统,提升协作(如管理员群聊)。

二、实时数据的基本使用

  1. 后端设置:用Socket.io创建服务器,监听事件。
  2. 前端连接:import io from ‘socket.io-client’;socket = io(url)。
  3. 发送/接收:socket.emit(‘chat’, msg);socket.on(‘chat’, (msg) => { … })。
  4. 认证:连接时emit JWT,服务器验证。

示例:后端 io.on('connection', socket => { socket.on('chat', msg => { io.emit('chat', msg); }); });

接下来,通过项目实践这些。

三、实现完整项目:带WebSocket实时聊天的认证用户系统

项目目标:扩展第十篇的Vue前端和Express后端,添加聊天室路由/组件。只有认证用户可访问,消息实时广播,用Vuex管理消息列表(state.messages)。这是一个独立的完整full-stack实时应用,后端用Socket.io服务器,前端客户端连接。

步骤 1: 后端准备(扩展Express项目)

基于第八篇的Express项目(user-manager-express),安装socket.iosocketio-jwt(用于JWT验证):npm install socket.io socketio-jwt

更新server.js(整合到现有app):

const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const socketioJwt = require('socketio-jwt');
const jwt = require('jsonwebtoken'); // 从第八篇
// ... 其他导入(如mongoose、routes,从前文)const app = express();
const server = http.createServer(app);
const io = socketIo(server, { cors: { origin: '*' } }); // 允许CORS// WebSocket 认证中间件
io.use(socketioJwt.authorize({secret: 'your_jwt_secret', // 与第八篇匹配handshake: true
}));io.on('connection', (socket) => {console.log('用户连接:', socket.decoded_token.username); // 从JWT获取用户socket.on('chatMessage', (msg) => {const message = {username: socket.decoded_token.username,text: msg,timestamp: new Date()};io.emit('chatMessage', message); // 广播给所有连接用户});socket.on('disconnect', () => {console.log('用户断开');});
});// ... 现有app.use(routes)等
const PORT = 3000;
server.listen(PORT, () => console.log(`服务器运行在端口 ${PORT}`));
  • 解释:用socketio-jwt验证连接(客户端发送JWT);on(‘chatMessage’)接收并广播。

步骤 2: 前端准备(扩展Vue项目)

基于第十篇的Vue项目,安装socket.io-clientnpm install socket.io-client

更新Vuex store(src/store/index.js),添加聊天状态:

// ... 同第十篇
state: {// ... 现有messages: [],socket: null
},
mutations: {// ... 现有ADD_MESSAGE(state, message) {state.messages.push(message);},SET_SOCKET(state, socket) {state.socket = socket;}
},
actions: {// ... 现有initSocket({ commit, state }) {if (!state.socket) {const socket = io('http://localhost:3000', {query: { token: state.token } // 发送JWT});commit('SET_SOCKET', socket);socket.on('chatMessage', (message) => {commit('ADD_MESSAGE', message);});}},sendMessage({ state }, text) {if (state.socket) {state.socket.emit('chatMessage', text);}}
}

步骤 3: 创建聊天组件

新建src/components/ChatRoom.vue

<template><div><h1>实时聊天室</h1><ul><li v-for="(msg, index) in messages" :key="index">[{{ msg.timestamp }}] {{ msg.username }}: {{ msg.text }}</li></ul><input v-model="newMessage" placeholder="输入消息" /><button @click="send">发送</button></div>
</template><script>
import { mapGetters, mapActions } from 'vuex';export default {data() {return { newMessage: '' };},computed: {...mapGetters(['messages', 'isAuthenticated'])},methods: {...mapActions(['initSocket', 'sendMessage']),send() {if (this.newMessage) {this.sendMessage(this.newMessage);this.newMessage = '';}}},created() {if (this.isAuthenticated) {this.initSocket();} else {this.$router.push('/login');}}
};
</script>

更新路由(src/router/index.js),添加聊天路由:

// ... 同第十篇
const routes = [// ... 现有{ path: '/chat', name: 'Chat', component: () => import('../components/ChatRoom.vue'), meta: { requiresAuth: true } }
];

步骤 4: 运行和测试

  • 后端:node server.js(localhost:3000)。
  • 前端:npm run serve(localhost:8080)。
  • 测试:登录后访问/chat,initSocket连接(发送JWT);输入消息发送,实时显示在所有连接客户端(多浏览器测试);未认证重定向;断开不崩溃。
  • 这是一个完整的带实时聊天的full-stack应用!WebSocket与Vuex/Vue Router无缝整合。

步骤 5: 扩展(可选)

  • 房间:用socket.join(‘room’)分群聊。
  • 持久化:将消息存MongoDB,加载历史。
  • 通知:emit用户特定事件。

四、常见问题与调试

  • 连接失败?检查CORS、JWT密钥;console.log(socket事件)。
  • 消息不广播?验证emit/on事件名匹配。
  • 认证错误?确保query.token发送,io.use正确。
  • 性能?大型聊天用rooms或Redis pub/sub。

总结

通过本篇,您入门了实时数据,用WebSocket(Socket.io)实现聊天功能。带实时聊天的认证用户系统证明了互动full-stack应用。

下一篇文章:数据库高级查询:MongoDB 聚合管道在用户数据分析中的应用,实现报告生成。我们将用聚合分析用户数据,提升洞察力。如果有疑问,欢迎评论!

(系列导航:这是第11/20篇。关注我,跟着学完整系列!)

http://www.dtcms.com/a/391304.html

相关文章:

  • 五传输层-TCP UDP慢启动-真题
  • ARM基础知识
  • 从零开始的指针(5)
  • TDMQ CKafka 版客户端实战指南系列之二:消费消息最佳实践
  • Comcast 没有对比就没有伤害
  • AI悬浮窗 1.0 | 快捷提取文字,总结信息,支持提取文字、理解屏幕上的图案、总结分析信息
  • MySQL、PostgreSQL、MongoDB和Redis全面对比
  • 隐私保护与数据安全合规(七)
  • 登录 双层拦截器+redis
  • TM56M152A (SOP16) HITENX海速芯 8位微控制器MCU 芯片深度解析
  • 理解元学习器 - 如何使用机器学习估计异质处理效应(四)
  • [数据结构] Map和Set
  • [Go类库分享]Go template模版库
  • 辅助搜题系统-基于模糊搜索,上传word题库后,可搜索答案
  • 【完整源码+数据集+部署教程】遥感农田森林岩石图像分割系统: yolov8-seg-C2f-DCNV2
  • RTX 4090助力深度学习:从PyTorch到生产环境的完整实践指南
  • AWS中国云中的调用链监控(EC2版)
  • CI/CD到底是什么?
  • 3dmax三维动画渲染很慢怎么办?
  • ASIS CTF 2025 SatoNote
  • BasicForm的使用
  • CSP初赛——STL中的函数整理
  • 小杰机器学习高级(two)——极大似然估计、交叉熵损失函数
  • 关于px4 1.15.0电机控制有效矩阵的更新
  • 【设计模式】职责链模式
  • 22届考研(华为oD)-Java面经
  • 轻松实践:用Python实现“名字大作战”游戏,表白Zulu
  • EasyDSS视频直播点播平台如何为游戏直播提供超强技术底座?
  • MySQL----MVCC机制
  • 设计|str增量法|计算贡献