不停的刷新 node 报socket hang up ,求解,是不是和缓冲区有关?
发布于 2年前 作者 zhuwenlong 3078 次浏览

读取一个文件,然后输出输出,一般情况下正常,可是我要是不停地按F5就会有一定几率报 socket hang up 错误,请问是什么问题,是不是要用缓冲区处理?

http.createServer(function(req,res){
    var html=fs.readFileSync('./static/css/base.css');
    res.writeHead(200,{"Content-Type" : "text/html"});
    res.write(html);
    res.end();
    console.log('ok')
    //var pathname = url.parse(req.url).pathname; 
    //router(pathname,req,res);
}).listen(port);

然后不停地刷新,就会报下面的错误

Error: socket hang up
at createHangUpError (http.js:1360:15)
at ServerResponse.OutgoingMessage._writeRaw (http.js:507:26)
at ServerResponse.OutgoingMessage._send (http.js:476:15)
at ServerResponse.OutgoingMessage.end (http.js:887:18)
at Server.<anonymous> (F:\kuaipan\node\zhuwenlong\server.js:14:13)
at Server.EventEmitter.emit (events.js:99:17)
at HTTPParser.parser.onIncoming (http.js:1914:12)
at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:111:23)
at Socket.socket.ondata (http.js:1811:22)
at TCP.onread (net.js:404:27)
8 回复

同步读取啊~用异步方法

node版本? 0.8.20之后向已关闭的socket连接写入数据会抛出异常。不断F5的过程中,浏览器客户端确实有可能在发起新请求之前,关闭前一个请求的socket连接,从而导致res的写入失败。

异步也是同样的问题后来我才改成同步测试的 发现还是这样的

之前用的是0.8.20

对了 那我如何在写入之前去判断这个socket已经被关闭了呢?

@zhuwenlong 简单但是非正规的方法就是每次res写入前检查res.socket,大概这样:

if(!res.socket || res.socket.destroyed){
   cosole.warn('client socket closed,oop!');
   return res.end();
}

说非正规是因为socket属性没有明显写在官方api文档上,以后有可能会取消这个属性。

正规点就是用domain,在res写入任何东西前

   var reqd = domain.create()
    reqd.add(req)
    reqd.add(res)

    // On error dispose of the domain
    reqd.on('error', function (error) {
      console.error('Error', error, req.url)
      reqd.dispose()
    })

不过domain模块还不成熟,api有可能变化,同样让人纠结。

我也遇到了类似的问题,我把问题整理放到了这个gist

@shiedman 有什么思路吗?谢谢

  1. HEAD请求不应该在header后再发送任何字节,就算0\r\n\r\n也不行,至少http.Server不欢迎这种做法。
  2. req.endres.end后的括号不可省略,否则coffee认为这是属性而不是方法。

PS: generated javascripts would be more appreciated than coffescript.

@shiedman <3 <3 <3 <3 <3 <3 <3 茅塞顿开的节奏啊,太感谢你了!

回到顶部