javascript - 使用带有nodejs的服务器发送事件并使用react的问题

标签 javascript node.js reactjs real-time server-sent-events

我需要执行server-sent-events给我的node js并响应应用程序,
我对此进行了一些研究,并遵循了一些在线教程,尤其是 site因为它的简单。

我的目标是有 1 条路线称为/api/alert

如果我们使用 JSON 对象向该路由发出 HTTP POST 请求,例如

{
  "longtitude": 100, 
  "latitude": 35, 
  "userId": "5dc28160e8a69c203002383b"
}

然后服务器将其存储在 MongoDB 中并实时发送给客户端(当然使用服务器发送的事件)

如果我们制作 HTTP GET 请求此路由,它将显示 中的所有当前对象MongoDB 每次新对象发布时,它都会获取新对象。

它就像我想要的那样工作。但是问题来了。
它会实时显示数据库中的对象和新的对象,直到正好 2 分钟后,不知何故连接丢失或发生某些事情使浏览器再次调用 GET/api/alert 然后所有相同的数据已经显示的又显示了。只要我什么都不做,重复就会每 2 分钟发生一次。

我做了很多研究

Failed to load resource: net::ERR_INCOMPLETE_CHUNKED_ENCODING



并尝试不同的方法来解决,但它似乎根本没有帮助。

这是一个nodejs还是 react 问题。关于我做错了什么或与这个问题有关的任何想法。感谢所有帮助。

这些是我的代码,它基于此 https://alligator.io/nodejs/server-sent-events-build-realtime-app/ 上的大部分内容:

Node 代码:
const { Fire } = require("../models/fire");

let clients = [];

// Iterate clients list and use write res object method to send new nest
function sendEventsToAll(newFire) {
  clients.forEach(c => {
    c.res.write(`data: ${JSON.stringify(newFire)}\n\n`);
  });
}

module.exports.addAlert = async (req, res, next) => {
  const fire = new Fire(req.body);
  res.send(await fire.save());

  return sendEventsToAll(fire);
};

module.exports.handleAlert = async (req, res, next) => {
  const headers = {
    "Content-Type": "text/event-stream",
    Connection: "keep-alive",
    "Cache-Control": "no-cache"
  };
  res.writeHead(200, headers);
  res.flushHeaders();

  const data = await Fire.find();
  res.write(`data: ${JSON.stringify(data)}\n\n`);

  // Generate an id based on timestamp and save res
  // object of client connection on clients list
  // Later we'll iterate it and send updates to each client
  const clientId = Date.now();
  const newClient = {
    id: clientId,
    res
  };
  clients.push(newClient);
  console.log(`${clientId} Connection opened`);

  // When client closes connection we update the clients list
  // avoiding the disconnected one
  req.on("close", () => {
    console.log(`${clientId} Connection closed`);
    clients = clients.filter(c => c.id !== clientId);
    res.end();
  });
};

react 代码:
import React, { useState, useEffect } from "react";
import "./App.css";

function App() {
  const [nests, setNests] = useState([]);
  const [listening, setListening] = useState(false);

  useEffect(() => {
    if (!listening) {
      const events = new EventSource("http://localhost:3900/api/alert");
      events.onmessage = event => {
        const parsedData = JSON.parse(event.data);

        setNests(nests => nests.concat(parsedData));
      };

      setListening(true);
    }
  }, [listening, nests]);

  return (
    <table className="stats-table">
      <thead>
        <tr>
          <th>_id</th>
          <th>longtitude</th>
          <th>latitude</th>
          <th>userId</th>
        </tr>
      </thead>
      <tbody>
        {nests.map((nest, i) => (
          <tr key={i}>
            <td>{nest._id}</td>
            <td>{nest.longtitude}</td>
            <td>{nest.latitude}</td>
            <td>{nest.userId}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}
export default App;

我遇到的问题的图片

image of the problem I encountered

最佳答案

Nodejs 有 2 分钟的默认超时,这就是你的连接在两分钟后关闭的原因。如果您希望它打开更长的时间,那么您需要增加默认超时时间。

关于javascript - 使用带有nodejs的服务器发送事件并使用react的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60072391/

相关文章:

jquery-ui - 如何在 React JS 中使用 jQuery UI

node.js - 包 react 不满足它的 sibling

javascript - 在桌面上查看时如何展开 Bootstrap 3 下拉菜单?

javascript - 为什么 javascript 返回另一件事而 php 返回另一件事?

javascript - 配置 Node 以使用 Object.assign

c# - node.js 与 C# 中的网络爬虫性能

json - 将 JSON 加载到 React/Node/Express 通用应用程序中,但不将其捆绑

javascript - 错误 : document. getElementsByTagName(...)[0] 的来源未定义

Javascript:在对象数组中的对象上调用方法

javascript - 具有新元素的 Nodemailer