当前位置: 首页 > 面试题库 >

nodejs / express-将stdout立即流式传输到客户端

平庆
2023-03-14
问题内容

我产生了以下孩子:var spw = spawn('ping', ['-n','10', '127.0.0.1'])我希望在客户端( 浏览器
)上 一个接一个地 而不是整体接收ping结果。

到目前为止,我已经尝试过了:

app.get('/path', function(req, res) {
   ...
   spw.stdout.on('data', function (data) {
      var str = data.toString();
      res.write(str + "\n");
   });
   ...
}

然后:

...
spw.stdout.pipe(res);
...

在这两种情况下,浏览器都将等待10次ping操作,然后将结果整体打印出来。我想让他们一个接一个,如何实现呢?

(客户只是在拨打电话.../path并用console.log记录结果)

编辑:
尽管我确实相信websockets是实现这一点所必需的,但我只是想知道是否还有其他方法。我看到了几个令人困惑的SO答案,并且博客文章(在这篇文章中,在第一步中,OP将日志发送到浏览器中)没有帮助,因此我决定悬赏一笔以引起注意。


问题答案:

这是使用SSE(服务器发送的事件)的完整示例。这适用于Firefox,也可能适用于Chrome:

var cp = require("child_process"),
         express = require("express"),
         app = express();

app.configure(function(){
    app.use(express.static(__dirname));
});


app.get('/msg', function(req, res){
    res.writeHead(200, { "Content-Type": "text/event-stream",
                         "Cache-control": "no-cache" });

    var spw = cp.spawn('ping', ['-c', '100', '127.0.0.1']),
    str = "";

    spw.stdout.on('data', function (data) {
        str += data.toString();

        // just so we can see the server is doing something
        console.log("data");

        // Flush out line by line.
        var lines = str.split("\n");
        for(var i in lines) {
            if(i == lines.length - 1) {
                str = lines[i];
            } else{
                // Note: The double-newline is *required*
                res.write('data: ' + lines[i] + "\n\n");
            }
        }
    });

    spw.on('close', function (code) {
        res.end(str);
    });

    spw.stderr.on('data', function (data) {
        res.end('stderr: ' + data);
    });
});

app.listen(4000);

和客户端HTML:

<!DOCTYPE Html>
<html> 
<body>
   <ul id="eventlist"> </ul>

   <script>              
    var eventList = document.getElementById("eventlist");
    var evtSource = new EventSource("http://localhost:4000/msg");

    var newElement = document.createElement("li");
    newElement.innerHTML = "Messages:";
    eventList.appendChild(newElement);


    evtSource.onmessage = function(e) {
        console.log("received event");
        console.log(e);
        var newElement = document.createElement("li");

        newElement.innerHTML = "message: " + e.data;
        eventList.appendChild(newElement);
    };

    evtSource.onerror = function(e) {
        console.log("EventSource failed.");
    };

    console.log(evtSource);

    </script>

</body>
</html>

运行node index.js并将您的浏览器指向http://localhost:4000/client.html。请注意,由于我正在运行OSX,因此必须使用“ -c”选项而不是“ -n”。



 类似资料:
  • 我有一个在远程服务器(debian linux)上运行的Java应用程序。该应用程序将运行时信息记录到文件中。 偶尔,支持人员需要使用客户端工具(不是在服务器上运行,而是在支持人员的桌面上运行)分析日志。然后,该工具需要远程访问 < li >服务器上的旧日志文件 < li >当前日志文件(实时增长) 我正在搜索一种良好的(=标准,灵活,安全,调试良好等)方式将这些过去和现在的日志消息流式传输到我的

  • 问题内容: 我正在使用NodeJ(带有Express),并且试图将zip文件流式传输回客户端。zip中包含的文件不在文件系统上,而是动态创建的。我想将文件内容流式传输到zip并将流式传输回客户端。 IE浏览器,我希望客户端收到: 快速创建1,2,3.txt并将其流式传输到zip文件。这可能吗? 问题答案: 存档器具有一个append方法,使您可以将文本另存为文件。要将数据“流化”给用户,您可以简单

  • 我正在尝试编写同时使用gRPC和REST的服务。实现技术有Java、Spring-Boot和gRPC。使用场景示例如下: 目的是有外部客户端可以通过RESTendpoint和/或通过进行gRPC调用与应用程序交互。在内部,有“网关”服务提供外部接口,并负责在外部客户端和执行实际工作的“域”服务之间传输/路由请求和响应。内部服务将通过gRPC进行通信。 外部客户端不知道如何在内部处理事情,域服务没有

  • 问题内容: 我遇到了一些问题,无论何时渲染视图,我都试图发送一个对象供我的Javascript客户端使用。我以这种方式发送(我正在使用车把) //然后在我的视图中,在脚本标签内,我尝试获取该var并进行打印 结果是这样的: 而且我不能使用它的任何属性,因为它是未定义的 问题答案: 您可以将对象作为字符串发送。 喜欢 在客户端,您可以解析它以获取对象 喜欢 现在您可以使用loc作为对象。

  • 嘿,伙计们,我目前已经实现了一个路线,负责根据他的请求从我的服务器上检索信息,现在我有兴趣将我的对象转移到坐在我视图中的客户端脚本。我可以使用Res.Render传输对象吗?

  • 问题内容: 我设法将文件从客户端大块上传到服务器,但是现在我想实现相反的方式。不幸的是,此部分缺少官方模块页面上的文档。 我要执行以下操作: 向服务器发出流和带有文件名的“下载”事件 服务器应创建一个readstream并将其通过管道传输到客户端发出的流 当客户端到达流时,将出现一个下载弹出窗口,并询问将文件保存在何处 我不想使用简单的文件超链接的原因令人困惑:服务器上的文件已加密并重命名,因此我