holepunchto / hyperswarm

A distributed networking stack for connecting peers.
https://docs.holepunch.to
MIT License
1.04k stars 84 forks source link

How to close a connection gracefully? #45

Closed KrishnaPG closed 4 years ago

KrishnaPG commented 4 years ago

Running the below code in two different terminals, if one instance is stopped (ctrl + c), the other instance just crashes !!

const hyperswarm = require('hyperswarm')
const crypto = require('crypto')
const swarm = hyperswarm()
const topic = crypto.createHash('sha256').update('my-hyperswarm-topic').digest()
swarm.join(topic, {lookup: true, announce: true})
swarm.on('connection', (socket, details) => {
  console.log('new connection!', details.peer)
})

The crash happens with below error:

events.js:186
      throw er; // Unhandled 'error' event
      ^

Error: read ECONNRESET
    at TCP.onStreamRead (internal/stream_base_commons.js:183:27)
Emitted 'error' event on Socket instance at:
    at emitErrorNT (internal/streams/destroy.js:91:8)
    at emitErrorAndCloseNT (internal/streams/destroy.js:59:3)
    at processTicksAndRejections (internal/process/task_queues.js:77:11) {     
  errno: 'ECONNRESET',
  code: 'ECONNRESET',
  syscall: 'read'
}

It is not clear why the app would crash if its peer exits. How to handle this gracefully?

Tried doing socket.end on the other app. But that would keep reconnecting.

mafintosh commented 4 years ago

You have to error handle the socket by attaching an onerror handler to the stream

KrishnaPG commented 4 years ago

Thank you. Calling socket.end() causes the connection to reconnect indefinitely. How to control this behavior? For example,

    swarm.on('connection', (socket, details) => {
        if(some condition met)
            socket.end(); // close the connection
    })

But this keeps reconnecting. How to avoid it, and just close (and stay closed) ?

freddi301 commented 3 years ago

a guess, @KrishnaPG tell if it works

swarm.on('connection', (socket, details) => {
  if(some condition met) {
    details.ban() // stop reconnecting to peer
    socket.end(); // close the connection
 }
})

https://github.com/hyperswarm/hyperswarm#infoban

KrishnaPG commented 3 years ago

Thank you @freddi301 Wouldn't ban() prohobit the reconnection to that peer forever (as in next time if we need to search, say, when the current active connection goes away and need to find alternatives)?

freddi301 commented 3 years ago

According to docs peers gets banned for queue.banned Option 1: info.ban() + hyperswarm({queue: {banned: 4000}}) Option 2: info.ban() + info.backoff() (found here https://github.com/hyperswarm/hyperswarm#infobackoff) Option 3: info.ban(true) (found here https://github.com/hyperswarm/hyperswarm/blob/master/lib/peer-info.js#L113) Option 4: use underlying modules to implement your own swarm (https://github.com/hyperswarm)

what is your goal?