Search code examples
javascriptnode.jssocketstcpserver

node.js TCP socket receive data and send out modified data works only for the first time


I want to create node.js TCP socket,which receives data,modifies data and then sends it back.I used this answer as my example: https://stackoverflow.com/a/24876432/1945451 it works just perfect when it is just like that,but after I add my own code to send data it works only for the first time.

My added code:

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
});

After adding this part of code the TCP socket starts working only for the first time.The first time it works as wanted,but on the second time it throws this error:

Error: This socket has been ended by the other party

and points out to this line:

conn.write(modData);

What the client part does:

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

What I want the server part to do:

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.

The server part takes only a second to finish everything,so I can guarantee that there won't be more than 1 connection at a time.

Thanks in advance!


Solution

  • I realised that everytime socket receives data it creates a new event handler(not sure how they are called) in this part of code:

    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
    });
    

    Everytime it receives data it creates this handler:

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

    so when connection is over and I end the socket,there is still this event handler left,so after second connection occurs and sends more data this line executes again:

    api.requestMatchDetails(data);
    

    which calls 2 handlers(the old one and the new one). The old handler tries to write to socket which has been closed so an error occurs. I fixed it by using "once" handler.For example,

    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
    });
    

    "once" handler works only one time and after it destroys itself.

    I am not very similar with Javascript or its terms,so I am not sure how to call certain things,I tried my best to explain,so if someone else has the same problem,they can understand my answer.