mirror of
https://github.com/fluencelabs/js-libp2p-websockets
synced 2025-04-24 20:12:32 +00:00
99 lines
2.6 KiB
JavaScript
99 lines
2.6 KiB
JavaScript
'use strict'
|
|
|
|
const EventEmitter = require('events')
|
|
const os = require('os')
|
|
const multiaddr = require('multiaddr')
|
|
const { createServer } = require('it-ws')
|
|
const debug = require('debug')
|
|
const log = debug('libp2p:websockets:listener')
|
|
log.error = debug('libp2p:websockets:listener:error')
|
|
|
|
const toConnection = require('./socket-to-conn')
|
|
|
|
module.exports = ({ handler, upgrader }, options = {}) => {
|
|
const listener = new EventEmitter()
|
|
|
|
const server = createServer(options, async (stream) => {
|
|
let maConn, conn
|
|
|
|
try {
|
|
maConn = toConnection(stream)
|
|
log('new inbound connection %s', maConn.remoteAddr)
|
|
conn = await upgrader.upgradeInbound(maConn)
|
|
} catch (err) {
|
|
log.error('inbound connection failed to upgrade', err)
|
|
return maConn && maConn.close()
|
|
}
|
|
|
|
log('inbound connection %s upgraded', maConn.remoteAddr)
|
|
|
|
trackConn(server, maConn)
|
|
|
|
if (handler) handler(conn)
|
|
listener.emit('connection', conn)
|
|
})
|
|
|
|
server
|
|
.on('listening', () => listener.emit('listening'))
|
|
.on('error', err => listener.emit('error', err))
|
|
.on('close', () => listener.emit('close'))
|
|
|
|
// Keep track of open connections to destroy in case of timeout
|
|
server.__connections = []
|
|
|
|
let listeningMultiaddr
|
|
|
|
listener.close = () => {
|
|
server.__connections.forEach(maConn => maConn.close())
|
|
return server.close()
|
|
}
|
|
|
|
listener.listen = (ma) => {
|
|
listeningMultiaddr = ma
|
|
|
|
return server.listen(ma.toOptions())
|
|
}
|
|
|
|
listener.getAddrs = () => {
|
|
const multiaddrs = []
|
|
const address = server.address()
|
|
|
|
if (!address) {
|
|
throw new Error('Listener is not ready yet')
|
|
}
|
|
|
|
const ipfsId = listeningMultiaddr.getPeerId()
|
|
|
|
// Because TCP will only return the IPv6 version
|
|
// we need to capture from the passed multiaddr
|
|
if (listeningMultiaddr.toString().indexOf('ip4') !== -1) {
|
|
let m = listeningMultiaddr.decapsulate('tcp')
|
|
m = m.encapsulate('/tcp/' + address.port + '/ws')
|
|
if (listeningMultiaddr.getPeerId()) {
|
|
m = m.encapsulate('/p2p/' + ipfsId)
|
|
}
|
|
|
|
if (m.toString().indexOf('0.0.0.0') !== -1) {
|
|
const netInterfaces = os.networkInterfaces()
|
|
Object.keys(netInterfaces).forEach((niKey) => {
|
|
netInterfaces[niKey].forEach((ni) => {
|
|
if (ni.family === 'IPv4') {
|
|
multiaddrs.push(new multiaddr.Multiaddr(m.toString().replace('0.0.0.0', ni.address)))
|
|
}
|
|
})
|
|
})
|
|
} else {
|
|
multiaddrs.push(m)
|
|
}
|
|
}
|
|
|
|
return multiaddrs
|
|
}
|
|
|
|
return listener
|
|
}
|
|
|
|
function trackConn (server, maConn) {
|
|
server.__connections.push(maConn)
|
|
}
|