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

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

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

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

  1. var Koa = require("koa");
  2. var Router = require("@koa/router");
  3.  
  4. const PORT = 3000;
  5.  
  6. var app = new Koa();

  7. var router = new Router();
  8.  
  9. const requestLogger = async (ctx, next) => {

  10. await next();

  11. ctx.app.emit(</span>response<span class="pl-pds">, ctx);

  12. };
  13.  
  14. app.use(requestLogger);
  15.  
  16. router.get("/", (ctx, next) => {

  17. ctx.body = "hello world";

  18. });
  19.  
  20. router.get("/api", (ctx, next) => {

  21. ctx.body = {

  22. status: 0,

  23. foo: "bar"

  24. };

  25. });
  26.  
  27. router.get("/test", (ctx, next) => {

  28. ctx.body = "hello test";

  29. });
  30.  
  31. router.get("/monitor", async ctx => {

  32. const res = ctx.res;

  33. ctx.status = 200;

  34. res.setHeader("Content-Type", "text/html");

  35. res.write(</span>&lt;h3&gt;net monitor&lt;h3&gt;<span class="pl-pds">);

  36. return new Promise(() => {

  37. ctx.app.on("response", data => {

  38. 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">);

  39. });

  40. });

  41. });
  42.  
  43. app.use(router.routes()).use(router.allowedMethods());
  44.  
  45. app.listen(PORT);

  46. 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 类型响应实现后台请求的监听

问题

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

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

相关资源

利用 chunked 类型响应实现后台请求的监听的更多相关文章

  1. Self Host模式下的ASP. NET Web API是如何进行请求的监听与处理的?

    构成ASP.NET Web API核心框架的消息处理管道既不关心请求消息来源于何处,也不需要考虑响应消息归于何方.当我们采用Web Host模式将一个ASP.NET应用作为目标Web API的宿主时, ...

  2. ASP.NET Core真实管道详解[2]:Server是如何完成针对请求的监听、接收与响应的【上】

    Server是ASP .NET Core管道的第一个节点,负责完整请求的监听和接收,最终对请求的响应同样也由它完成.Server是我们对所有实现了IServer接口的所有类型以及对应对象的统称,如下面 ...

  3. Server是如何完成针对请求的监听、接收与响应1

    Server是如何完成针对请求的监听.接收与响应的[上] Server是ASP .NET Core管道的第一个节点,负责完整请求的监听和接收,最终对请求的响应同样也由它完成.Server是我们对所有实 ...

  4. 不会吧,这也行?iOS后台锁屏监听摇一摇

    目录 背景介绍 探索过程 其他 APP 有没有类似功能 系统提供的摇一摇回调能否满足 其他方法能否实现 利用 CoreMotion 框架,监听加速计原始数据 通过加速计监听摇一摇 控制器相关逻辑和代码 ...

  5. andriod开发,简单的封装网络请求并监听返回.

    一.为什么封装 因为android 4.0 以后的发送网络请求必须要放到异步线程中,而异步线程必须跟handle合作才能更新主线程中的UI,所以建议用一个类继承handler来异步处理网络请求. 二. ...

  6. java事件响应方法汇总(容器类监听、监听器类、AbstractAction、反射)

    Java图形用户界面中,处理事件时所必须的步骤是: 1.创建接受响应的组件(控件)2.实现相关事件监听接口3.注册事件源的动作监听器4.事件触发时的事件处理 相应的可以通过以下的集中方式来作出事件响应 ...

  7. 权限管理demo-Http请求前后监听工具

    工具作用: 1. 输出每次请求的参数 2. 接口的请求时间 package com.mmall.common; import com.mmall.util.JsonMapper; import lom ...

  8. 利用MutationObserver对页面元素的改变进行监听

    'use strict'; let MutationObserver = window.MutationObserver || window.WebKitMutationObserver || win ...

  9. 利用Python的pyHook包来进行键盘监听

    最近在实习的时候发现一件很蛋疼的事情,那就是我们组的项目因为有后台进程,所有每次运行完以后后台进程都必须要自己手动关闭,每次编译之前忘记关就会有一大堆编译错误,我就想直接弄个可以快捷键直接关闭算了   ...

随机推荐

  1. webpack打包出现WARNING in configuration The 'mode' option has not been set, webpack will fallback to 'production' for this value. 错误

    打包运行的时候出现以下错误 WARNING in configurationThe 'mode' option has not been set, webpack will fallback to ' ...

  2. 面试连环炮系列(二十一):你们的项目怎么使用kafka

    你们的项目怎么使用kafka? 我们采用kafka进行日志采集,准确点说是ELK方案,即elasticsearch + logstash + kibana + kafka.通过Spring AOP的方 ...

  3. 一起学Spring之注解和Schema方式实现AOP

    概述 在上一篇,我们了解了通过实现接口和XML配置的方式来实现AOP,在实现注解方式AOP之前,先了解一下AspectJ.AspectJ是一个面向切面的框架,它扩展了Java语言,定义了AOP语法,能 ...

  4. C#程序编写高质量代码改善的157个建议【20-22】[泛型集合、选择集合、集合的安全]

    建议20.使用泛型集合来替代非泛型集合 http://www.cnblogs.com/aehyok/p/3384637.html 这里有一篇文章,是我之前专门来介绍泛型的.我们应尽量的使用泛型集合.因 ...

  5. 控制DIV移动

    键盘控制DIV移动 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> < ...

  6. 关于使用DB2数据库的项目后台报-420错误码的问题

    ###  Error querying database.  Cause: com.ibm.db2.jcc.am.SqlDataException: DB2 SQL Error: SQLCODE=-4 ...

  7. 集合系列 Map(十五):TreeMap

    TreeMap 是 Map 集合的有序实现,其底层是基于红黑树的实现,能够早 log(n) 时间内完成 get.put 和 remove 操作. public class TreeMap<K,V ...

  8. React: 研究Flux设计模式

    一.简介 一般来说,State管理在React中是一种最常用的实现机制,使用这种state管理系统基本可以开发各种需求的应用程序.然而,随着应用程序规模的不断扩张,原有的这种State管理系统就会暴露 ...

  9. Maven项目使用mybatis报错 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found):

    maven项目使用mybatis时,找不到mapper文件(.xml) 错误信息提示: 项目可以正常运行,但是在有请求到达服务器时(有访问数据库的请求),会出现报错!! 错误原因: mybatis没有 ...

  10. 整理h5移动端适配方案

    <使用Flexible实现手淘H5页面的终端适配>:https://github.com/amfe/article/issues/17 <再聊移动端页面的适配>:https:/ ...