如何实现数据成功入库后通过WebSocket向前端发送通知?
实现批量插入数据库后通过WebSocket发送通知的解决方案
需求说明
后端接口/getImages需完成以下流程:
- 读取
log.txt文件中的URL列表 - 将所有URL批量插入数据库
images表 - 全部插入成功后,通过WebSocket向前端发送通知:「数据已成功上传,即将展示数据」
- 查询
images表数据并返回给前端展示
原代码存在的问题
- 循环内重复创建WebSocket服务器,且每次插入后都执行查询,导致资源浪费和逻辑混乱
- 异步插入操作未做统一等待,无法判断所有数据是否已完成插入
- 前后端WebSocket端口不匹配(后端创建在8081端口,前端连接8000端口)
- 前端未监听WebSocket消息,无法接收后端通知
修改后的后端代码
const fs = require('fs'); const WebSocketServer = require('ws').Server; // 全局创建WebSocket服务器,避免路由内重复初始化 const wss = new WebSocketServer.Server({ port: 8081 }); // 封装数据库查询为Promise,简化异步流程控制 function queryDB(sql) { return new Promise((resolve, reject) => { connection.query(sql, (err, result) => { if (err) reject(err); else resolve(result); }); }); } loginrouter.get('/getImages', cors(), async (req, res) => { try { // 读取并处理log.txt,过滤空行避免无效插入 const array = fs.readFileSync('log.txt').toString().split("\n") .filter(url => url.trim() !== ''); // 批量执行插入,等待所有操作完成 const insertPromises = array.map(url => { const sql = `INSERT into images (urls) values ('${url.trim()}')`; return queryDB(sql); }); await Promise.all(insertPromises); // 所有插入完成后,给所有连接的WebSocket客户端发通知 wss.clients.forEach(client => { if (client.readyState === client.OPEN) { client.send('数据已成功上传,即将展示数据'); } }); // 查询数据库并返回结果 const queryResult = await queryDB("SELECT urls FROM `images`"); res.send(queryResult); } catch (err) { console.error('操作失败:', err); res.status(500).send('服务器内部错误'); } });
修改后的前端代码
<html> <head> </head> <body> <button type="button" onclick="getImage(event)"> Show Images</button><br /> <h1 style="text-align: center; color: blue">Here are the Results:</h1> <div id="notification" style="text-align:center; color:green; font-size:18px; margin:10px 0;"></div> <div id="demo" style="display:flex; flex-wrap:wrap; justify-content:center;"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.2.1/axios.js" integrity="sha512-SXo2rCaEJmbAPoxtaSjW+/hLaVCMAJ1CX8XnIP02x6/LIaWQp4GipKxQhBwL8Tn5U/K+lD9AaM4f4mXJdKnDQw==" crossorigin="anonymous" referrerpolicy="no-referrer"> </script> <script> let exampleSocket; function initWebSocket() { // 连接后端WebSocket服务器(http用ws协议,https用wss) exampleSocket = new WebSocket("ws://localhost:8081"); exampleSocket.onopen = function(event) { console.log('WebSocket连接已建立'); }; // 监听后端发送的通知并展示 exampleSocket.onmessage = function(event) { document.getElementById('notification').textContent = event.data; }; exampleSocket.onerror = function(err) { console.error('WebSocket连接错误:', err); }; } // 页面加载时初始化WebSocket连接 window.onload = initWebSocket; function getImage(e) { e.preventDefault(); console.log("开始加载图片数据"); axios.get("http://localhost:8000/getImages", { headers: { "Content-Type": "application/json" } }).then((response) => { console.log(response.data); const demoContainer = document.getElementById("demo"); demoContainer.innerHTML = ''; // 清空旧内容 // 根据返回数据动态渲染图片,避免硬编码循环次数 response.data.forEach(item => { if (item.urls) { const img = document.createElement('img'); img.src = item.urls; img.style = "border:1px solid black;margin:4px; width:100px; height:100px"; img.alt = "图片"; demoContainer.appendChild(img); } }); }).catch(err => { console.error('获取图片数据失败:', err); }); } </script> </body> </html>
关键改进点
后端:
- 全局初始化WebSocket服务器,避免重复创建资源
- 用
Promise.all等待所有插入操作完成,确保通知时机准确 - 封装数据库操作为Promise,简化异步逻辑
- 过滤空行数据,避免无效插入
前端:
- 页面加载时提前建立WebSocket连接,确保能及时接收通知
- 添加通知展示区域,直观显示后端提示信息
- 动态渲染图片,适配返回数据的实际长度
- 增加错误处理,提升页面稳定性
内容的提问来源于stack exchange,提问作者f180111 Yousaf Zahid
相关产品推荐
相关产品推荐

