node + vue 实现服务端单向推送消息,利用EventSource
场景:后台系统需要实时收到电池报警消息,并语音提醒,前台不需要发送任何东西,所以想的是,服务端单向推送
1. 实现EventSource参考博客:
https://www.jqhtml.com/41272.html
https://developer.mozilla.org/zh-CN/docs/Web/API/Server-sent_events/Using_server-sent_events
2. 利用events监听触发事件,主动推送消息
前端代码
<script type="text/javascript"> if(typeof(EventSource)!=="undefined"){ let source=new EventSource("http://192.168.254.244:3001/api/messageNotic"); source.addEventListener('test',function(e){ console.log(e) }); source.onmessage=function(event) { console.log(event) document.getElementById("result").innerHTML+=event.data + "<br>"; }; }else{ document.getElementById("result").innerHTML="抱歉,你的浏览器不支持 server-sent 事件..."; } </script>
后端代码
// 可读流 const Readable = require('stream').Readable; function RR() { Readable.call(this, arguments); } RR.prototype = new Readable(); RR.prototype._read = function (data) { } const sse = (stream, event, data) => { return stream.push(`event:${event}\ndata: ${JSON.stringify(data)}\n\n`) } exports.messageNotic = async (ctx, next) => { let stream = new RR() ctx.set({ 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', Connection: 'keep-alive' }); // sse(stream, 'test', { remindFlag: new Date() }); ctx.body = stream; // 每过30秒,发送一条注释语,保持和web端的连接。 interval = setInterval(function () { sse(stream, 'test', { remindFlag: new Date() }); }, 1000 * 30); // 监听当web端关闭eventSource, 清除定时器 ctx.req.connection.addListener("close", function () { clearInterval(interval); }, false); }
到了这步,其实可以完成推送了,
但是如果想在产生报警日志的时候,发送提醒消息,就需要继续操作,
借用events依赖,当监听到某个事件的触发,就主动推送一条消息,
改造之后的代码如下:
// events事件
const events = require('events');
const eventEmitter = new events.EventEmitter();
// 增加一个监听事件 // 当监听到abnormalHandler 异常函数触发,往前端推送带有报警得消息 async function abnormalHandler() { eventEmitter.emit("abnormalHandler"); } function RR() { Readable.call(this, arguments); } RR.prototype = new Readable(); RR.prototype._read = function (data) { } const sse = (stream, event, data) => { return stream.push(`event:${event}\ndata: ${JSON.stringify(data)}\n\n`) } exports.messageNotic = async (ctx, next) => {
当监听到abnormalHandler事件触发,就主动推送一条消息 eventEmitter.on("abnormalHandler", function () { console.log("data_receive ---> connection"); sse(stream, 'test', { remindFlag: 1 }); }); var stream = new RR() ctx.set({ 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', Connection: 'keep-alive' }); // sse(stream, 'test', { remindFlag: new Date() }); ctx.body = stream; // 每过30秒,发送一条注释语,保持和web端的连接。 interval = setInterval(function () { sse(stream, 'test', { remindFlag: new Date() }); }, 1000 * 30); // 监听当web端关闭eventSource, 清除定时器 ctx.req.connection.addListener("close", function () { clearInterval(interval); }, false); }
本文来自博客园,作者:时光凉忆,转载请注明原文链接:https://www.cnblogs.com/naturl/p/15049186.html
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)