Node.js + Express 3 + Socket.io = 在发送响应后不能设置响应头

7

我是一个新手,正在学习node.js,似乎遇到了一个无法解决的错误。

这是一个非常简单的初学者代码,所以不需要太多解释,而且在本地主机上运行良好,但在生产服务器上出现问题。

App.js

var express = require('express')
  , routes = require('./routes')
  , http = require('http')
  , path = require('path');

var app = express();

app.configure(function(){
  app.set('port', process.env.PORT || 8000);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.favicon());
  app.use(express.logger('dev'));
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(path.join(__dirname, 'public')));
});

app.configure('development', function(){
  app.use(express.errorHandler());
});

app.get('/', routes.index);

var server = app.listen(8000);
var io = require('socket.io').listen(server);

server.listen(app.get('port'), function(){
  console.log("Express server listening on port " + app.get('port'));
});

以下是可怕的错误信息!

http.js:644
    throw new Error('Can\'t set headers after they are sent.');
          ^
Error: Can't set headers after they are sent.
    at ServerResponse.OutgoingMessage.setHeader (http.js:644:11)
    at ServerResponse.res.setHeader (/home1/artalatc/public_html/cloud1/node_modules/express/node_modules/connect/lib/patch.js:59:22)
    at next (/home1/artalatc/public_html/cloud1/node_modules/express/node_modules/connect/lib/proto.js:153:13)
    at Function.app.handle (/home1/artalatc/public_html/cloud1/node_modules/express/node_modules/connect/lib/proto.js:198:3)
    at Server.app (/home1/artalatc/public_html/cloud1/node_modules/express/node_modules/connect/lib/connect.js:66:31)
    at Manager.handleRequest (/home1/artalatc/public_html/cloud1/node_modules/socket.io/lib/manager.js:564:28)
    at Server.<anonymous> (/home1/artalatc/public_html/cloud1/node_modules/socket.io/lib/manager.js:118:10)
    at Server.EventEmitter.emit (events.js:115:20)
    at HTTPParser.parser.onIncoming (http.js:1793:12)
    at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:111:23)

问题似乎出在var io = require('socket.io').listen(server);这一行,注释掉该行代码可以解决错误。

请发布你的路由文件。错误不是来自index.jade文件。 - c0deNinja
已添加。这是一个自动生成的文件。 - user1574965
开发时没有错误,但是在生产环境中出现了问题? - c0deNinja
不确定这是否与此有关...但是var socket = io.connect('http://localhost');在生产环境中无法工作。也许从您的index.jade文件中删除它,看看是否仍然会出现错误。在开发中,这很好用,因为您的服务器和客户端都在本地主机上。但在生产中不行。客户端和服务器是不同的。 - c0deNinja
虽然你是对的,这是一个愚蠢的错误,但即使修复它也不能解决问题。 - user1574965
经进一步调查,注释掉 var io = require('socket.io').listen(server); 似乎可以消除错误。 - user1574965
10个回答

7

你使用的是哪个版本的Node?

当我使用0.9.x时,我遇到了同样的问题。我将Node降级到了0.8.4,问题似乎解决了。

我最好的猜测是,Node中的某些内容与Socket.io不兼容。


我也是这样做的。问题已经解决了。 - user1574965
2
有没有办法让它能够在较新版本的 Node 上工作? - Jimbali

4

升级express - 3.1.0和socket.io - 0.9.13

在nodejs0.10上可以正常工作。


这对我来说是解决方案。谢谢! Node v0.10.0,Express 3.1.0和Socket.io 0.9.13。 - Bryan Hales

2

2

已经尝试过了,问题出在 var io = require('socket.io').listen(server); 这一行。也可以查看这个线程:https://github.com/visionmedia/express/issues/1265 - user1574965

1

这种方法适用于当前稳定版本0.8.14:

var express = require('express')
  , app = express()
  , server = app.listen(8000)
  , io = require('socket.io').listen(server);

1

对于遇到这个问题的任何人,您应该使用:

var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
server.listen(8000);

由于Express不再返回Socket.io所需的HTTP实例。请参阅更新的README.md文件,了解有关Express 2和3示例的详细信息https://github.com/learnboost/socket.io


0

这个错误是因为Express内部使用缓存,也就是说对于每个第二个请求,数据都会从缓存中获取,因此它会以304状态码响应返回,请使用

app.disable('etag');

它告诉Express每个请求都是新的,意味着状态码为200


0

我之前遇到过完全一样的问题。是因为express和socket.io版本不兼容所导致的。我将它们升级到了express 3.2.4和socket.io 0.9.14,现在一切运作得非常好。

或者你可以将socket.io降级到之前的版本,但这个你需要自己想办法解决。


0
运行 npm list socket.io
确保它不会显示如下无效内容,
─ socket.io@0.9.10 invalid
npm ERR! invalid: socket.io@0.9.10 c:\Users....
如果出现此错误,请安装 npm install socket.io。 还要确保其他软件包也是相同的。

0

在 package.json 中将 socket.io 依赖项更改为 0.9.15,运行 npm install,它应该可以解决你的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接