Socket.io is causing the error 'Error: Can't set headers after they are sent.'

Socket.io is causing the error 'Error: Can't set headers after they are sent.'

我正在尝试使用 Angular 2、node.js、express 和 mongo 将节点 Web 应用程序部署到 ibm-cloud。 我的应用程序在不添加 socket.io 要求行的情况下工作正常:

const io = require("socket.io")(server);

但是,每次我尝试添加 socket.io 并执行容器时,控制台记录(针对每个请求):

Error: Can't set headers after they are sent. at SendStream.headersAlreadySent (/app/node_modules/send/index.js:390:13) at SendStream.send (/app/node_modules/send/index.js:618:10) at onstat (/app/node_modules/send/index.js:730:10) at FSReqWrap.oncomplete (fs.js:153:5) Error: Can't set headers after they are sent. at SendStream.headersAlreadySent (/app/node_modules/send/index.js:390:13) at SendStream.send (/app/node_modules/send/index.js:618:10) at onstat (/app/node_modules/send/index.js:730:10) at FSReqWrap.oncomplete (fs.js:153:5) Error: Can't set headers after they are sent. at SendStream.headersAlreadySent (/app/node_modules/send/index.js:390:13) at SendStream.send (/app/node_modules/send/index.js:618:10) at onstat (/app/node_modules/send/index.js:730:10) at FSReqWrap.oncomplete (fs.js:153:5)

这是我的代码 // 取消注释以启用 zipkin 跟踪,根据您的网络配置进行定制: // var appzip = require('appmetrics-zipkin')({ // 主机:'localhost', //端口:9411, // 服务名称:'frontend' // });

    require('appmetrics-dash').attach();
    require('appmetrics-prometheus').attach();
    const appName = require('./../package').name;
    const http = require('http');
    const express = require('express');
    const log4js = require('log4js');
    const localConfig = require('./config/local.json');
    const path = require('path');
    const logger = log4js.getLogger(appName);
    logger.level = process.env.LOG_LEVEL || 'info'
    const app = express();
    const server = http.createServer(app);
    const io = require("socket.io")(server);


    app.use(log4js.connectLogger(logger, { level: logger.level }));
    require('./routers/index')(app, server);

    // Add your code here
    const bodyParser = require('body-parser');
    var cors = require('cors');
    const jwt = require("jsonwebtoken");

    const { mongoose } = require("./database");

    app.use(cors());
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({
      extended: true
    }));

    app.use("/auth", require("./routes/auth.routes"));
    app.use(
      "/usuarios",
      (req, res, next) => {
        const bearerHeader = req.headers["authorization"];
        if (typeof bearerHeader !== "undefined") {
          const bearer = bearerHeader.split(" ");
          const bearerToken = bearer[1];
          jwt.verify(bearerToken, "loremipsum", (err, authData) => {
            if (err) return res.sendStatus(403);
            authData.rol == "admin" ? next() : res.sendStatus(403);
            return;
          });
        } else {
          res.sendStatus(403);
        }
      },
      require("./routes/usuarios.routes")
    );

    app.use("/api", (req, res, next) => {
      const bearerHeader = req.headers["authorization"];
      console.log(bearerHeader);
      if (typeof bearerHeader !== "undefined") {
        const bearer = bearerHeader.split(" ");
        const bearerToken = bearer[1];
        jwt.verify(bearerToken, "loremipsum", (err, authData) => {
          if (err) return res.sendStatus(403);
          req.authData = authData;
          next();
        });
      } else {
        res.sendStatus(403);
      }
    });
    app.use("/api/turnos", require("./routes/turns.routes"));
    app.use("/api/estado", require("./routes/estados.routes"));
    app.use("/api/incidencias", require("./routes/incidencia.routes"));
    app.use("/movil/api", require("./routes/movil.data.routes"));
    app.use("/movil/estadisticas", require("./routes/cola.routes"));
    app.use('/*', (req,res,next) => {
      res.sendFile(path.join(__dirname, '../public', 'index.html'));
      return;
    } )
    //end my code

    const port = process.env.PORT || localConfig.port;
    server.listen(port,'0.0.0.0', function(){
      logger.info(`tfgbff listening on http://localhost:${port}/appmetrics-dash`);
      logger.info(`OpenAPI (Swagger) spec is available at http://localhost:${port}/swagger/api`);
      logger.info(`Swagger UI is available at http://localhost:${port}/explorer`);
    });

    const turno = require("./controllers/turnos.controller");
    const io = require('socket.io')(server);
    io.on("connection", socket => {
      console.log("conectao!");
      turno.nextSubject.subscribe(turnos => {
        turnos = turnos.filter(t => t.atendido == false);
        const infoTurno = turnos.map(t => {
          return {
            incidenciaId: t.incidenciaId,
            turno: t.turno,
            siendoAtendido: t.siendoAtendido
          };
        });
        console.log(infoTurno);
        io.emit("socket-turnos", infoTurno);
      });
      socket.on("disconnect", () => console.log("desconectao!"));
    });
    // app.use(function (req, res, next) {
    //   res.sendFile(path.join(__dirname, '../public', '404.html'));
    // });

    // app.use(function (err, req, res, next) {
    //  res.sendFile(path.join(__dirname, '../public', '500.html'));
    // });

    module.exports = server;

非常感谢!

我知道这是旧问题,但我刚刚遇到了完全相同的问题,并且刚刚发现它是由 appmetrics 库引起的。

一旦我弄清楚如何让它工作,我会更新它。

编辑:

OK 设法让它与 appmetrics-dash 一起工作。您需要使用 monitor() 而不是 attach() 并将监视器移动到路线的末尾。我调查了 appmetrics-prometheus,现阶段它只有一个 attach(),所以不能使用:

const dash = require('appmetrics-dash');

const express = require('express');
const history = require('connect-history-api-fallback');

const app = express();
const server = require('http').Server(app);

require('./routers/index')(app, server);
require('./services/index')(app);

// Add your code here

dash.monitor({server});

// catch 404 and forward to error handler
app.use(function(req, res) {
    res.status(404).send('Not Found');
});

// error handler
app.use(function(err, req, res) {
    res.status(err.status || 500).send('Error');
});

server.listen(env.port, () => {
    logger.info(`${env.name} listening on ${env.url}/appmetrics-dash`);
    logger.info(`${env.name} listening on ${env.url}`);
});