我有一个奇怪的场景,我不知道如何解决它。
我在nodejs中有一个简单的tcp聊天服务器,我的客户端当前使用的是本地C#,最终将转移到Unity。我有自己的网络库,可以创建TCP连接并处理消息等,在某些情况下工作正常,直到断开连接。
服务器在EC2实例上运行,我在PC上加载两个窗口来测试多个连接。当我关闭窗口时,我在nodejs服务器控制台
中收到此错误Error: read ECONNRESET
at exports._errnoException (util.js:870:11)
at TCP.onread (net.js:544:26)
哪个好,因为这是它工作的场景。我猜这只是意味着连接突然关闭(关闭窗口)。
但是当我指示套接字关闭时会出现问题。
我正在将我的客户端移植到Unity,当关闭客户端时,它不会产生此ECONNRESET
错误,并且连接永远不会突然关闭(就像我期望的那样),所以在这种情况下我必须手动关闭客户端上的连接,这会导致不同的错误。
Error: This socket has been ended by the other party
at Socket.writeAfterFIN [as write] (net.js:268:12)
at /opt/chat/chat.js:32:10
at Array.forEach (native)
at broadcast (/opt/chat/chat.js:31:10)
at Socket.<anonymous> (/opt/chat/chat.js:26:2)
at emitNone (events.js:72:20)
at Socket.emit (events.js:166:7)
at endReadableNT (_stream_readable.js:905:12)
at nextTickCallbackWith2Args (node.js:441:9)
at process._tickCallback (node.js:355:17)
当我在服务器上收到此错误时,其他连接的客户端可以继续向服务器发送消息,但是他们无法从服务器接收消息。
我的nodejs服务器是从github这里提取的:
https://gist.github.com/creationix/707146
// Load the TCP Library
net = require('net');
// Keep track of the chat clients
var clients = [];
// Start a TCP Server
net.createServer(function (socket) {
// Identify this client
socket.name = socket.remoteAddress + ":" + socket.remotePort
// Put this new client in the list
clients.push(socket);
// Send a nice welcome message and announce
socket.write("Welcome " + socket.name + "\n");
broadcast(socket.name + " joined the chat\n", socket);
// Handle incoming messages from clients.
socket.on('data', function (data) {
broadcast(socket.name + "> " + data, socket);
});
// Remove the client from the list when it leaves
socket.on('end', function () {
clients.splice(clients.indexOf(socket), 1);
broadcast(socket.name + " left the chat.\n");
});
// Send a message to all clients
function broadcast(message, sender) {
clients.forEach(function (client) {
// Don't want to send it to sender
if (client === sender) return;
client.write(message);
});
// Log it to the server output too
process.stdout.write(message)
}
}).listen(5000);
// Put a friendly message on the terminal of the server.
console.log("Chat server running at port 5000\n");
方案
假设我们左侧有客户A ,右侧有客户B
在初次连接时,他们都可以聊天。
CLIENT B 希望断开连接,代码通过终止套接字强制断开连接。 nodejs服务器收到错误“此套接字已被另一方结束”并广播此播放器已断开与客户端A
客户端A 希望继续通信,无论是否有人连接。 客户端A 继续输入和发送消息,但是一旦 CLIENT B 断开连接,就不会收到消息。但是,消息确实正在发送到服务器。
客户端A 没有收到自己的消息。
客户B 希望重新连接以继续聊天并执行此操作。 客户端A 发送消息'hello' 客户B 发送消息'hello'
客户端B 正在看到这两条消息,并且正在进行正常聊天,但是客户端A 没有看到任何消息,并且卡在试图读取的阻止呼叫上数据
仅当我强行关闭套接字时,它才会收到ECONNRESET
错误时完全正常。我该如何复制此错误或修复我的问题?
修改
我设法重现了ECONNRESET
错误,现在它可以正常工作,但它仍然无法解释为什么它不能与其他错误一起使用。
C#Close
中的方法GetStream().Close
和TcpClient
不足以正常关闭连接。相反,我必须直接访问套接字并关闭它。
直接关闭套接字可以在本机C#应用程序中使用,但不能在Unity中使用。
要在Unity中复制此错误,我必须使用
Shutdown(SocketShutdown.Receive);