Node.js 发送标头后无法设置标头。socket.io发生错误

Node.js 发送标头后无法设置标头。socket.io发生错误,node.js,sockets,Node.js,Sockets,我正在编写一个非常简单的nodejssocket.io应用程序。不知何故,这种返回在发送错误后无法设置头。但我看不到标题再次设置的点。我只调用了server.listen一次,我相信socket.listen是独立工作的,所以它不应该冲突 我知道“无法设置标题”错误已发布多次。我已经简单地阅读了它们,我也理解response.writeHead在正常情况下是如何工作的。我用response.writeHead试用了一些node.js应用程序,它们在大多数情况下都工作得很好。似乎我在这里遗漏了一些

我正在编写一个非常简单的nodejssocket.io应用程序。不知何故,这种返回在发送错误后无法设置头。但我看不到标题再次设置的点。我只调用了server.listen一次,我相信socket.listen是独立工作的,所以它不应该冲突

我知道“无法设置标题”错误已发布多次。我已经简单地阅读了它们,我也理解response.writeHead在正常情况下是如何工作的。我用response.writeHead试用了一些node.js应用程序,它们在大多数情况下都工作得很好。似乎我在这里遗漏了一些东西。是由于socket.io造成的吗

const fs = require("fs");

const server = require("http").createServer();
const io = require("socket.io").listen(server);

server.listen(52273,function(){
  console.log("server up");
});

server.on("request",function(request,response){
  fs.readFile("mainpage.html",function(error,data){
    response.writeHead(200,{"Content-Type":"text/html"});
    response.end(data);
  });
});

io.sockets.on("connection",function(socket){

  var roomName = null;
  socket.on("join", function(data){
    roomName = data;
    socket.join(data);
    console.log("client joined" + data);
  });

  socket.on("message",function(data){
    io.sockets.in(roomName).emit("message","test");
  });
});

您使用的节点版本是什么

我们在使用0.9.x时遇到了同样的问题。我将节点降级到0.8.4,问题似乎消失了


我的最佳猜测是Node中的某些内容发生了变化,Socket.io与之不符。

了解一下Socket.io如何与您的web服务器协同工作可能会有所帮助。io使用webSocket协议作为其基本协议。webSocket连接从一个HTTP请求开始,该请求中设置了特殊的头,以指示webSocket连接的开始。正常运行的web服务器将看到此webSocket头,并将请求移交给webSocket处理程序以启动webSocket连接

但是,您拥有的这个处理程序:

server.on("request",function(request,response){
  fs.readFile("mainpage.html",function(error,data){
    response.writeHead(200,{"Content-Type":"text/html"});
    response.end(data);
  });
});
看起来它正在响应每一个到达的请求并发送响应,不管请求是什么。因此,我可以想象,当webSocket请求传入时,您将发送两个响应,一个来自webSocket服务器代码,另一个来自上面的请求处理程序

可能,您需要能够只发送mainpage.html响应,以获取不是webSocket请求的特定URL

要了解更多信息,请在此处插入console.log:

server.on("request",function(request,response){
  console.log(request.url);
  fs.readFile("mainpage.html",function(error,data){
    response.writeHead(200,{"Content-Type":"text/html"});
    response.end(data);
  });
});

而且,您可能会看到您正在将mainpage.html发送到webSocket请求,这不是您想要做的。您可能需要添加一些if逻辑,以便请求处理程序避免webSocket请求。

谢谢大家。通过将express安装到我的实验应用程序中,我解决了这个问题。我再次阅读了手册,发现socket.io v2现在需要express app作为依赖项。我似乎一直在使用socket.iov2,但不知何故还是坚持使用socket.iov1风格的应用程序编写。当我将它降级到socket.io v1时,它也起作用


TL;DR-socket.io v2与为socket.io v1编写的应用程序不兼容。如果socket.io应用程序返回的内容在发送错误后无法设置标题,请尝试使用正确版本的socket.io或安装正确的依赖项。

谢谢您的评论。我会试着降低我的排名,谢谢你的详细回复。但上次在fs.readfile方法的右括号}上发现了错误。页面最初加载Fine,这意味着它在webSocket请求之后工作正常,然后崩溃。我想我应该尝试使用不同版本的node.js和socket.io。我会带着结果回来。@SungryeolPark-是的,如果问题如我所描述的那样,那就是错误所在。您的webSocket处理程序已发送传入webSocket连接的响应,但您的通用请求处理程序正在尝试发送另一个响应,这是不允许的。使用不同版本的socket.io不是这里的问题。你的密码坏了。您只需要在请求特定URL时发送mainpage.html,而不需要在收到任何请求时发送mainpage.html,因为您正在尝试发送mainpage.html,即使webSocket请求进来,但这是错误的。@SungryeolPark-将console.logrequest.URL放入您的请求处理程序中,确定webSocket连接时显示的URL,然后添加一个if语句,当它是webSocket URL时不发送任何响应。