zoukankan      html  css  js  c++  java
  • 利用 chunked 类型响应实现后台请求的监听

    Koa 中实现 chunked 数据传输 中介绍了如何在 Koa 中实现 Transfer-Encoding:chunked 类型的响应分片传输。这里来看一个应用场景。

    假如我们想监听后台的请求,并将监听到的数据打印到页面。那么复用 chunked 类型的响应,我们只需要解决如何在页面 controller 中获取到别的 controller 被执行。

    Koa 在 app 上有提供一个 emit 方法派发事件。这样,可以写一个中间件对请求进行拦截,并且派发事件。然后在在监听的地方可通 app.on 来响应事件,假设我们展示监听数据的页面 url 为 /monitor,在 /monitor 的 controller 中实现 chunked 数据响应,并且监听前面中间件发来的数据,然后不断输出到页面,达到了监听的效果。

    实现后代码大概是这样子:

    var Koa = require("koa");
    var Router = require("@koa/router");
    

    const PORT = 3000;

    var app = new Koa();
    var router = new Router();

    const requestLogger = async (ctx, next) => {
    await next();
    ctx.app.emit(</span>response<span class="pl-pds">, ctx);
    };

    app.use(requestLogger);

    router.get("/", (ctx, next) => {
    ctx.body = "hello world";
    });

    router.get("/api", (ctx, next) => {
    ctx.body = {
    status: 0,
    foo: "bar"
    };
    });

    router.get("/test", (ctx, next) => {
    ctx.body = "hello test";
    });

    router.get("/monitor", async ctx => {
    const res = ctx.res;
    ctx.status = 200;
    res.setHeader("Content-Type", "text/html");
    res.write(</span>&lt;h3&gt;net monitor&lt;h3&gt;<span class="pl-pds">);
    return new Promise(() => {
    ctx.app.on("response", data => {
    res.write(</span></span> <span class="pl-s"> &lt;details&gt;</span> <span class="pl-s"> &lt;summary&gt;</span> <span class="pl-s"> &lt;a hre="<span class="pl-s1"><span class="pl-pse">${</span><span class="pl-smi">data</span>.<span class="pl-smi">url</span><span class="pl-pse">}</span></span>"&gt;<span class="pl-s1"><span class="pl-pse">${</span><span class="pl-smi">data</span>.<span class="pl-smi">url</span><span class="pl-pse">}</span></span>&lt;/a&gt;</span> <span class="pl-s"> &lt;/summary&gt;</span> <span class="pl-s"> &lt;pre&gt;<span class="pl-s1"><span class="pl-pse">${</span><span class="pl-c1">JSON</span>.<span class="pl-c1">stringify</span>(<span class="pl-smi">data</span>.<span class="pl-c1">body</span>, <span class="pl-c1">null</span>, <span class="pl-c1">2</span>)<span class="pl-pse">}</span></span>&lt;pre&gt;</span> <span class="pl-s"> &lt;/details&gt;</span> <span class="pl-s"> <span class="pl-pds">);
    });
    });
    });

    app.use(router.routes()).use(router.allowedMethods());

    app.listen(PORT);
    console.info(</span>server started at http://localhost:<span class="pl-s1"><span class="pl-pse">${</span><span class="pl-c1">PORT</span><span class="pl-pse">}</span></span><span class="pl-pds">);

    运行效果:

    利用 chunked 类型响应实现后台请求的监听

    利用 chunked 类型响应实现后台请求的监听

    问题

    • Transfer-Encoding:chunked 依赖于客户端与服务器之间建立的这个连接一直处于未完成的状态,只要服务端不主动 res.end() 掉。但服务器配置 keep alive 的时长设置会影响到该连接,超时后会断开,当然可以将限制调大。
    • 因为在 /monitor 这个页面中,它没有办法知道其他路由的到达与结束,所以这里复用了事件。使得在 /monitor 页面能够监听到其他 controller 的情况。但这种做法会面临内存增长过快的问题,因为连接和事件监听一直保持着。

    但如果仅用于调试数据,比如查看页面发生了哪些请求,返回了什么数据,这种一次性暂时的需求,还是没问题的。

    相关资源

  • 相关阅读:
    一起谈.NET技术,抛砖引玉:我看微软.NET各子技术领域之应用前景 狼人:
    一起谈.NET技术,Windows Mobile 6.5的开始菜单 狼人:
    一起谈.NET技术,ASP.NET MVC 验证方式(1) 狼人:
    一起谈.NET技术,强烈推荐体验VisualStudio2010 RC 狼人:
    【华安php入门系列】第1天php的执行方式、执行过程
    败者树Java实现
    Android INSTALL_FAILED_ACWF_INCOMPATIBLE
    《构建高质量的C#代码》,新书上市,欢迎交流!
    oracle中的左右连接
    VS2012 UPDATE 2 发布了离线包
  • 原文地址:https://www.cnblogs.com/Wayou/p/koa_request_monitor.html
Copyright © 2011-2022 走看看