node.js TCP套接字接收数据并发送修改后的数据仅适用于第一次

时间:2016-01-10 14:34:08

标签: javascript node.js sockets tcp server

我想创建node.js TCP套接字,它接收数据,修改数据然后将其发送回来。我使用这个答案作为我的例子:https://stackoverflow.com/a/24876432/1945451当它就是这样时,它的工作原理很完美,但是在我添加自己的代码来发送数据后,它只能在第一次工作。

我添加的代码:

conn.on('data', function(data) {
    console.log('ECHO_SERVER: CONN: GOT DATA: ' + data);
    //ADDED PART STARTS HERE
    data = Number(data);
    api.requestMatchDetails(data);
    api.on("matchDetailsData", function (matchId, matchData) {
        var modData = "..." + matchData.match.something + "...";
        conn.write(modData);
    });
    //ADDED PART ENDS HERE
});

添加这部分代码后,TCP套接字才第一次开始工作。第一次按预期工作,但第二次抛出此错误:

错误:此套接字已被另一方结束

并指出这一行:

conn.write(modData);

客户部分的作用:

1. Opens connection
2. Sends data
3. Waits for response
4. Closes socket.

我希望服务器部件做什么:

1. Wait for connection
2. Accept connection
3. Receive data
4. Modify data
5. Send back data.
6. Close connection
7. Wait for more connections.

服务器部分只需一秒即可完成所有操作,因此我可以保证一次不会有超过1个连接。

提前致谢!

1 个答案:

答案 0 :(得分:0)

我意识到每次socket接收数据都会在这段代码中创建一个新的事件处理程序(不确定它们是如何被调用的):

conn.on('data', function(data) {
    console.log('ECHO_SERVER: CONN: GOT DATA: ' + data);
    //ADDED PART STARTS HERE
    data = Number(data);
    api.requestMatchDetails(data);
    api.on("matchDetailsData", function (matchId, matchData) {
        var modData = "..." + matchData.match.something + "...";
        conn.write(modData);
    });
    //ADDED PART ENDS HERE
});

每次收到数据时,都会创建此处理程序:

api.on("matchDetailsData", function (matchId, matchData) {
    var modData = "..." + matchData.match.something + "...";
    conn.write(modData);
});

所以当连接结束并且我结束套接字时,仍然会有这个事件处理程序,所以在第二次连接发生并发送更多数据后,这一行再次执行:

api.requestMatchDetails(data);

调用2个处理程序(旧处理程序和新处理程序)。旧处理程序尝试写入已关闭的套接字,以便发生错误。我通过使用“once”处理程序修复它。例如,

conn.once('data', function(data) {
    console.log('ECHO_SERVER: CONN: GOT DATA: ' + data);
    //ADDED PART STARTS HERE
    data = Number(data);
    api.requestMatchDetails(data);
    api.on("matchDetailsData", function (matchId, matchData) {
        var modData = "..." + matchData.match.something + "...";
        conn.write(modData);
    });
    //ADDED PART ENDS HERE
});

“曾经”处理程序只能运行一次并且在它自毁之后。

我与Javascript或其术语不太相似,所以我不确定如何调用某些东西,我尽力解释,所以如果其他人有同样的问题,他们就能理解我的答案。