Search code examples
node.jssocketsclientsetinterval

Using setInterval with socket.write


This is the code that works but it writes the data just once:

var net = require('net');
var PORT = 3000;
var client = new net.Socket();
client.connect(PORT, function(){
  client.write('{printing}');
})

I am looking to write the same thing every few seconds. Wrote the below code but it doesn't seem to work:

client.connect(PORT, function(){
   setInterval(function(){
     client.write('{ printing }');
   },10000);
 })

Following is the error that I keep getting:

node:events:355
      throw er; // Unhandled 'error' event
      ^

Error: write EPIPE
    at afterWriteDispatched (node:internal/stream_base_commons:160:15)
    at writeGeneric (node:internal/stream_base_commons:151:3)
    at Socket._writeGeneric (node:net:773:11)
    at Socket._write (node:net:785:8)
    at writeOrBuffer (node:internal/streams/writable:395:12)
    at Socket.Writable.write (node:internal/streams/writable:340:10)
    at Timeout._onTimeout (/app/src/index.js:135:14)
    at listOnTimeout (node:internal/timers:557:17)
    at processTimers (node:internal/timers:500:7)
Emitted 'error' event on Socket instance at:
    at emitErrorNT (node:internal/streams/destroy:188:8)
    at emitErrorCloseNT (node:internal/streams/destroy:153:3)
    at processTicksAndRejections (node:internal/process/task_queues:81:21) {
  errno: -32,
  code: 'EPIPE',
  syscall: 'write'
}
[nodemon] app crashed - waiting for file changes before starting..

This is how I fixed it:

client.connect(PORT, function(){
    client.write('printing')
  })

  //adding drain if the buffer gets full
  client.on('drain',()=>{
    console.log("draining the buffer")
    setTimeout(() => {
        client.write('printing')
    })

    //reading the response recieved : ("ok")
  client.on('data', (data) => {})

  //in case of an error, closing the connection
  client.on('error',err => {}).on('close',() => {
    setTimeout(() => {
      client.connect(PORT, function(){
        client.write('printing')
  
      })
    },40000)
  })

Solution

  • In this context, the EPIPE error probably means that you're trying to write to a socket that has been closed. Since the setInterval() example you show keeps going forever, that probably means that the socket you originally connected gets closed at some point, but your setInterval() is still firing and trying to write to it.

    You don't show the overall context of what you're trying to accomplish here to know exactly what to suggest, but at a minimum, you need to call clearInterval() to stop the timer whenever the socket it's trying to write to gets closed, either on purpose or because of error.

    Here's an example for how you could debug if this is what is happening to you:

    const net = require('net');
    const PORT = 3000;
    const client = new net.Socket();
    let timer;
    
    function disableTimer() {
       if (timer) {
           clearInterval(timer);
           timer = null;
       }
    }
    
    client.on('error', err => {
        console.log("socket error", err);
        disableTimer();
    }).on('close', () => {
        console.log("socket closed");
        disableTimer();
    });
    
    client.connect(PORT, function(){
       timer = setInterval(function(){
         client.write('{ printing }');
       },10000);
    });