проблема с использованием отправленных сервером событий с nodejs и реагирование - PullRequest
2 голосов
/ 05 февраля 2020

Мне нужно реализовать server-sent-events для моего node js и реагировать приложения, я провел некоторое исследование по этому поводу, и я следовал некоторым учебникам в Интернете, особенно на этом сайте из-за его простоты.

моя цель состоит в том, чтобы был 1 маршрут под названием / api / alert

, если мы сделаем HTTP-запрос POST к этому маршруту с объектом JSON, таким как

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

, то сервер сохранит его в MongoDB, а также отправит его клиенту в режиме реального времени (конечно, используя отправленные сервером события)

, если мы сделаем запрос HTTP GET на этот маршрут, то он покажет все текущие объекты в MongoDB , и он будет получать новый объект каждый раз, когда новый объект POST.

он работал так же, как я этого хочу. Но возникла проблема. он отображает объекты в БД и новый в режиме реального времени очень хорошо, пока ровно через 2 минуты, каким-то образом соединение теряется или происходит что-то, что заставляет браузер снова вызвать GET / api / alert, а затем все те же данные, которые уже отображается снова отображается. Дублирование происходит каждые 2 минуты, пока я ничего не делаю с ним.

Я много исследовал

Не удалось загрузить ресурс: net :: ERR_INCOMPLETE_CHUNKED_ENCODING

и попробуйте разные способы обхода, но это, похоже, совсем не помогает.

это nodejs или проблема реагирования. Любая идея о том, что я сделал не так или что-то делать с этой проблемой. Любая помощь приветствуется.

это мой код, он основан на большинстве того, что можно найти по этому https://alligator.io/nodejs/server-sent-events-build-realtime-app/:

Nodejs код:

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();
  });
};

Код реакции:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...