Server automatically getting closed and facing 'ERR_STREAM_WRITE_AFTER_END' error along with data sending every time to client

帅比萌擦擦* 提交于 2021-02-10 18:36:58

问题


I am trying to get real-time data using Server-Sent Events from the Database Mysql and sending the value to the client Reactjs. Here is the code:

server.js

const mysql = require('mysql');
const app = require('express')()
const fetch = require('node-fetch');

const con = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: 'root',
  database: 'databasetest',
});
var increment = 0;

app.get('/stream/:abc/:qwe', (request, response) => {
  console.log(`Request url: ${request.url}`);

  var startDate = request.params.abc
  var endDate = request.params.qwe

  request.on('close', () => {
    increment = increment - 1;
    closeConnection(response);
  });

  response.writeHead(200, {
    'Connection': 'keep-alive',
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Access-Control-Allow-Origin': '*'
  });

  setTimeout(() => {
    var initial_result;
    console.log("The connection number is ", (++increment))
    setInterval(() => {
      con.query('SELECT * FROM status_table where start_time BETWEEN ? and ?', [startDate, endDate], (err, rows) => {
  
        if (err) {
          console.log('error', err.message, err.stack)
        }

        if (JSON.stringify(rows) === JSON.stringify(initial_result)) {

        } else {
          if (Changed(initial_result, rows)) {
              let data = null;
              const url = "http://localhost:8080/data?startTime=" + startDate + "&endTime=" + endDate;
              data = getData(url);

              data.then(function (result) {
              console.log("Data is sent")
              response.write("event: executinghello\n");
              response.write('data: ' + JSON.stringify(result));
              response.write("\n\n");
              eventHistory.push(result);
              response.end()
            })
            
            initial_result = rows;
          }
        }

      })

      function Changed(pre, now) {
        if (pre != now) {
          return true
        } else {
          return false
        }
      }
    }, 5000);
 }, 3000);
});

app.listen(4001, () => console.log('SSE app listening on port 4001!'))

async function getData(url) {
  try {
    const response = await fetch(url);
    const json = await response.json();
    return json;
  } catch (error) {
    console.log(error);
    return error;
  }
};

function closeConnection(response) {
  if (!response.finished) {
    response.end();
    console.log('Stopped sending events.');
  }
}

client.js

 this.eventSource = new EventSource("http://localhost:4001/stream/"+startDate+"/"+endDate);
    this.eventSource.addEventListener("executinghello", e => {
      const data = JSON.parse(e.data);
      data.sort((a, b) => parseFloat(b.id) - parseFloat(a.id));
      this.setState({
       isLoaded: true,
       allData: data ,
     })
});

Using this I am able to get the data but after some seconds the connection gets closed and then if data is getting POST to DB then this gives an error as:

Data is sent
events.js:292
      throw er; // Unhandled 'error' event
      ^

Error [ERR_STREAM_WRITE_AFTER_END]: write after end
    at write_ (_http_outgoing.js:629:17)
    at ServerResponse.write (_http_outgoing.js:621:15)
    at Query.<anonymous> (C:\Users\Documents\socket-io-server\app.js:73:24)
    at Query.<anonymous> (C:\Users\Documents\socket-io-server\node_modules\mysql\lib\Connection.js:526:10)
    at Query._callback (C:\Users\Documents\socket-io-server\node_modules\mysql\lib\Connection.js:488:16)
    at Query.Sequence.end (C:\Users\Documents\socket-io-server\node_modules\mysql\lib\protocol\sequences\Sequence.js:83:24)
    at Query._handleFinalResultPacket (C:\Users\Documents\socket-io-server\node_modules\mysql\lib\protocol\sequences\Query.js:149:8)
    at Query.EofPacket (C:\Users\Documents\socket-io-server\node_modules\mysql\lib\protocol\sequences\Query.js:133:8)
    at Protocol._parsePacket (C:\Users\Documents\socket-io-server\node_modules\mysql\lib\protocol\Protocol.js:291:23)
    at Parser._parsePacket (C:\Users\Documents\socket-io-server\node_modules\mysql\lib\protocol\Parser.js:433:10)
Emitted 'error' event on ServerResponse instance at:
    at writeAfterEndNT (_http_outgoing.js:684:7)
    at processTicksAndRejections (internal/process/task_queues.js:85:21) {
  code: 'ERR_STREAM_WRITE_AFTER_END'
}

Not understanding what I have missed and the connections automatically getting closed. How to overcome the automatic connection end() issue? And how to get rid of this above Error? And can you please help me in sending the data from server to client only when there is a change in the data, if no change then the client should not be notified of the same? How to manage connections and close them when not in use? Can someone please help me with all the above queries? Thanks!


回答1:


In your code, you're calling response.end(), which will disconnected the event stream.

Normally, you would want to keep the event stream open indefinitely, unless you had a reason to close it. The client will disconnect itself if the browser tab is closed, connection is lost, etc.

Also, you might consider using an existing module like express-sse: https://www.npmjs.com/package/express-sse This can save you some time in implementing the protocol.



来源:https://stackoverflow.com/questions/64553979/server-automatically-getting-closed-and-facing-err-stream-write-after-end-erro

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!