• 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}
    data: ${JSON.stringify(data)}
    
    `)
    }
    
    
    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} data: ${JSON.stringify(data)} `) } 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); }
  • 相关阅读:
    [译]Vulkan教程(03)开发环境
    [译]Vulkan教程(02)概况
    [译]Vulkan教程(01)入门
    CSharpGL(57)[译]Vulkan清空屏幕
    CSharpGL(56)[译]Vulkan入门
    CSharpGL(55)我是这样理解PBR的
    CSharpGL(54)用基于图像的光照(IBL)来计算PBR的Specular部分
    [译]背景:着色的物理和数学(4)
    [译]背景:着色的物理和数学(3)
    [译]背景:着色的物理和数学(2)
  • 原文地址:https://www.cnblogs.com/naturl/p/15049186.html
Copyright © 2020-2023  润新知