使用流式 JSON 输出构建简单的 Nodejs API

2024-04-26

我正在尝试构建一个简单的基于 Node.js 的流 API。我想做的就是当我点击服务器 URL 时,输出应该流式传输一组测试数据(JSON),如 Twitter 流 API。

var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);

server.listen(8083);

app.get('/', function (req, res) {
    res.write(io.on('connection', function (socket) {
              socket.emit('item', { hello: 'world' });
    }));
});

所以,如果我这样做curl http://localhost:8083/,我想要输出类似:

$ curl http://localhost:8083/
{hello: 'world'}
{hello: 'world'}
{hello: 'world'}
{hello: 'world'}
...

我是 Node.js 和 Web 套接字的新手。我可能对节点工作原理的基础知识有严重错误,请让我知道最好的解决方案。


首先,最好将 JSONStream 部分放入中间件中,如下所示:

var _ = require('lodash');
// https://github.com/smurthas/Express-JSONStream/blob/master/index.js
function jsonStream(bytes) {
  return function jsonStream(req, res, next) {
    // for pushing out jsonstream data via a GET request
    var first = true;
    var noop = function () {};
    res.jsonStream = function (object, f) {
      f = _.isFunction(f) ? f : noop;
      if (!(object && object instanceof Object)) {
        return f();
      }

      try {
        if (first) {
          first = false;
          res.writeHead(200, {
            'Content-Type': 'application/json',
            'Cache-Control': 'no-cache',
            'Connection': 'keep-alive'
          });
        }
        res.write(JSON.stringify(object) + '\n');
      } catch (err) {
        return _.defer(f.bind(null, err));
      }
      f();
    };
    next();
  };
}

然后,假设您希望在每次有人连接到 socket.io 时通过此 API 收到通知

var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var _ = require('lodash');
var EventEmitter = require('events').EventEmitter;
server.listen(8083);

var mediator = new EventEmitter();

io.on('connection', function (socket) {
  mediator.emit('io:connection:new', socket);
});

// the second parameter, specify an array of middleware, 
// here we use our previously defined jsonStream
app.get('/', [jsonStream()], function (req, res) {

  function onNewConnection(socket) {
    res.jsonStream({
      type: 'newConnection',
      message: 'got a new connection',
      socket: {
        id: socket.id
      }
    });
  }

  // bind `onNewConnection` on the mediator, we have to use an mediator gateway
  // because socket.io does not offer a nice implementation of "removeListener" in 1.1.0
  // this way each time someone will connect to socket.io
  // the current route will add an entry in the stream
  mediator.on('io:connection:new', onNewConnection);

  // unbind `onNewConnection` from the mediator
  // when the user disconnects
  req.on('close', function () {
    mediator.removeListener('connection', onNewConnection);
  });

  res.jsonStream({
    type: 'welcome',
    message: 'waiting for connection'
  });
});

最后,如果您想在不连接到 socket.io 的情况下测试此代码,请使用以下模拟器:

// Simulate socket.io connections using mediator
(function simulate() {
  var dummySocket = {
    id: ~~(Math.random() * 1000)
  };
  mediator.emit('io:connection:new', dummySocket);
  setTimeout(simulate, Math.random() * 1000);
})();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用流式 JSON 输出构建简单的 Nodejs API 的相关文章

  • 我想使用 Sequelize 将 MySQL 中的对象数组存储在单个列中

    之前我正在寻找如何使用 Sequelize 在 MySQL 中插入对象数组 然后我找到了一种直接插入数组的解决方案 例如 1 2 在单列中 insert into TABLE NAME id marks VALUES 21 1 2 但我正在
  • 在气球内显示带有照片的多个地标的最佳做法是什么?

    我有一个项目如下 从手机上拍摄几张照片 将照片保存在网络系统中 然后将照片显示在其中的谷歌地球上 我读过很多文章 但它们都使用 fetchKml 我读过的一篇好文章是使用 php 但使用 fetchKml 我不知道是否可以使用 parseK
  • document.registerElement - 为什么我们需要指定“prototype”和“extends”?

    考虑我想扩展本地button元素 并创建我自己的super button元素 据我所知 它必须遵循以下模式 var SuperButton document registerElement super button prototype Ob
  • History.pushState和页面刷新

    我开始研究 HTML5 新历史 API 不过 我有一个问题 如何处理页面刷新 例如 用户单击一个链接 该链接由 js 函数处理 该函数 异步加载页面内容 使用history pushState 更改URL 用户刷新页面 但是服务器上当然不存
  • 使用 Jquery 更改 css 属性时的事件检测

    有没有办法检测元素的 显示 css 属性是否更改 是否更改为无 块或内联块 如果没有的话有什么插件吗 谢谢 Note 突变事件 https developer mozilla org en US docs Web Guide Events
  • 使用 WebSocket 是否会产生服务器成本?

    我已经离开了 PHP MySQL 的舒适区 因为语法 封装 过程的东西可能会让人沮丧 上周 我开始尝试并按照一些教程使用 Node js Socket IO 创建实时聊天应用程序 到目前为止 我从未使用过 WebSockets 做过任何事情
  • JSLint 错误:意外的“这个”

    无法理解为什么 JSLint 对我的使用感到惊讶this在下面的代码中 function testConstr x use strict this joker Whyyy sooo seriousss this x x 对于这两个属性分配
  • 未捕获的安全错误:阻止了具有原点的框架...访问具有原点的框架

    我已经为 SAP 解决方案 无论什么 制作了一个组件 该组件通过 iframe 嵌入到报告中 在 SAP 平台 BO 上部署报告后 我收到此错误 在 Chrome 上 但在 IE 或 FF 上也不起作用 Uncaught SecurityE
  • Android - 从服务器获取响应时验证 JSON 以避免 JSONException

    在我的一些与服务器通信并使用 http 获取响应的应用程序中 我使用 json 来格式化数据服务器端 当它到达设备时 我使用类似于我在 stackoverflow 上找到的代码 private class LoadData extends
  • 从 bash 脚本运行节点

    很简单 我正在尝试使用 cron 自动运行 nodejs 脚本 但是脚本本身似乎无法运行该文件 我的脚本很简单 usr bin env node node var node assets js update js 但是 在运行此命令时 它返
  • 将 DIV 转换为单击并拖动视口

    有人知道一种不显眼的 基于原型或无框架的方法将具有大内容 例如地图 的 DIV 转换为具有固定尺寸的可点击和可拖动的 地图 容器 非常像 Google 地图 我想在大型输入表单中显示 HTML 块 这些块可能会超出可用空间 每个块可以有大约
  • 如何在javascript中删除一组表情符号中的最后一个表情符号?

    假设我的字符串中有 3 个表情符号 字符串中没有任何空格或除表情符号之外的任何其他字符 如何删除javascript中最后一个表情符号 下面的答案不使用任何特殊的包并安全地删除最后一个表情符号 function safeEmojiBacks
  • 主干集合排序

    我制作了我的第一个主干应用程序 但在集合排序方面遇到了一些问题 使用这个后 var SortedFriends MyFriends sortBy function friend return friend get uid console l
  • 防止 Bootstrap IE 下拉列表在滚动条单击时关闭

    在 IE 中 单击下拉菜单滚动条时 下拉菜单将关闭 当您使用鼠标滚轮滚动它时 效果很好 这是代码层链接 https www codeply com go Uh8qadr3q2 https www codeply com go Uh8qadr
  • 将罗马数字转换为阿拉伯数字--recursiv

    我是 JavaScript 新手 正在网站的帮助下学习https www jshero net koans roman1 html https www jshero net koans roman1 html 本练习是编写一个转换器 将罗马
  • jQuery clone() 复制数据...有时...?

    使用下面的示例 我有一个tr我正在复制 它包含一个 jQueryautocomplete 第一次克隆时 自动完成功能不起作用 因为附加的data items 一片空白 第二次单击 添加 按钮时 自动完成功能将起作用 此后 再次单击 添加 会
  • 让管道自我刷新角度

    我有来自后端的静态时间戳 我想每 1 秒刷新一次管道以获取现在的日期 这是我的烟斗 import Pipe PipeTransform from angular core import moment from moment Pipe nam
  • 在状态中检测到不可序列化的值,路径为:`filters.startDate` (redux-toolkit.esm.js )

    我正在使用 React 18 和 Redux 构建一个预算应用程序 我不知道这里有什么问题 import moment from moment const filtersDefaultState text sortBy date start
  • 如何在javascript中设置从数据库输入的最大数量?

    我希望根据数据库中的数量设置 输入类型 数字 中输入的最大数量 目前 我正在尝试让它在数据最大的基础上工作 然后再尝试从数据库中获取最大值 但它似乎无法工作 之前已经在这里问过 但我仍然无法理解 在 php javascript 中设置数据
  • 无法读取解析推送通知包数据

    我尝试使用 Parse 推送通知服务发送自定义数据 但从 Bundle 中提取时总是返回 null 值 自定义广播接收器 Override public void onReceive Context context Intent inten

随机推荐