Pub/Sub 模型在Node.js中如何处理ETIMEDOUT与EPIPE?
发布于 2年前 作者 liuyanghejerry 1881 次浏览

Node.js新手。

最近使用Node.js的TCP实现一个Pub/Sub模型的应用,逻辑很简单。

比如有三个客户端A, B, C连接服务器S。服务器S负责转发ABC的数据,和聊天非常相似,但是是二进制的数据。

但是服务端上线之后,发现数据经常有错误。表现在客户端收到服务端转发来的数据,却无法正常解析。

我在日志中输出了socket遇到的所有错误,其中发现了大量类似这样的输出:

{ [Error: write ETIMEDOUT] code: 'ETIMEDOUT’, errno: 'ETIMEDOUT’, syscall: ‘write’ } { [Error: read ETIMEDOUT] code: 'ETIMEDOUT’, errno: 'ETIMEDOUT’, syscall: ‘read’ } { [Error: write ETIMEDOUT] code: 'ETIMEDOUT’, errno: 'ETIMEDOUT’, syscall: ‘write’ } { [Error: write EPIPE] code: 'EPIPE’, errno: 'EPIPE’, syscall: ‘write’ } { [Error: write EPIPE] code: 'EPIPE’, errno: 'EPIPE’, syscall: ‘write’ } { [Error: write EPIPE] code: 'EPIPE’, errno: 'EPIPE’, syscall: ‘write’ } { [Error: write EPIPE] code: 'EPIPE’, errno: 'EPIPE’, syscall: ‘write’ } { [Error: write EPIPE] code: 'EPIPE’, errno: 'EPIPE’, syscall: ‘write’ }

socket我是设置了setKeepAlive的,而且也设置了setNoDelay。

因为客户端通过服务端进行通信,数据包非常多,服务端将所有的数据做解析、验证,非常耗资源,所以这里想问一下,类似这样的错误该如何处理?

关键代码:

// server继承于net.Server server.on('listening’, function() { var port = server.address().port; }).on('connection’, function(cli) { cli.socketBuf = new Buffers(); cli.commandStarted = false; cli.dataSize = 0; cli.setKeepAlive(true); cli.setNoDelay(true); cli.on('connect’, function() { server.clients.push(cli); }).on('close’, function() { var index = server.clients.indexOf(cli); server.clients.splice(index, 1); }).on('data’, function (buf) { server.emit('data’, cli, buf); if(op.autoBroadcast) { _.each(server.clients, function© { if(c != cli) c.write(buf); }); } }).on('error’, function(err) { console.log(err); //上面日志输出的错误,都来自这里 }); }).on('error’, function(err) { console.log(‘Error with server!’); console.log(err); });

// …

// room.dataSocket 是上面对象的实例 room.dataSocket.on('data’, function(cli, d) { // bf是带有缓冲区的文件类 bf.append(d); room.dataFileSize += d.length;

}).on('connection’, function(con){ bf.readAll(function(da) { con.write(da); }); });

完整代码:https://github.com/liuyanghejerry/painttyServer/blob/master/socket.js

回到顶部