83 lines
2.2 KiB
JavaScript
83 lines
2.2 KiB
JavaScript
|
import { Server } from 'net'
|
||
|
import { unlink as fileDelete } from 'fs'
|
||
|
import btc from 'better-try-catch'
|
||
|
import Logger from 'simple-node-logger'
|
||
|
import ON_DEATH from 'death' //this is intentionally ugly
|
||
|
|
||
|
let logger = {
|
||
|
logFilePath:'logfile.log',
|
||
|
timestampFormat:'YYYY-MM-DD HH:mm:ss.SSS'
|
||
|
}
|
||
|
|
||
|
export default class Socket extends Server {
|
||
|
constructor (path, opts={}) {
|
||
|
super()
|
||
|
this.path = path
|
||
|
this.logger = Logger.createSimpleLogger(opts.logger ? opts.logger: logger)
|
||
|
} // end constructor
|
||
|
|
||
|
|
||
|
async create ( app ) {
|
||
|
|
||
|
this.on('error', async (err) => {
|
||
|
// recover from socket file that was not removed
|
||
|
if (err.code === 'EADDRINUSE') {
|
||
|
console.log(`socket path ${this.path} already exists...deleting`)
|
||
|
await fileDelete(this.path)
|
||
|
await this.listen(this.path)
|
||
|
return Promise.resolve(err.code)
|
||
|
}
|
||
|
// otherwise fatally exit
|
||
|
console.log('error creating socket: ',err.code)
|
||
|
return Promise.reject(err.code)
|
||
|
})
|
||
|
|
||
|
//
|
||
|
this.on('listening', async () => {
|
||
|
console.log(`socket created at ${this.path}`)
|
||
|
|
||
|
// this gets called for each client connection and is unique to each
|
||
|
this.on('connection', (socket) => {
|
||
|
console.log('new consumer connected')
|
||
|
|
||
|
socket.on('data', async (buf) => {
|
||
|
let [err, packet] = btc(JSON.parse)(buf.toString())
|
||
|
if (!err) {
|
||
|
this.logger.info(`data packet received to socket \n ${packet}`)
|
||
|
socket.write(JSON.stringify(await app.processPacket.bind(app)(packet)))
|
||
|
}
|
||
|
else { console.log(`bad packet JSON syntax \n ${buf.toString()}`)}
|
||
|
|
||
|
}) // end incoming data listerner
|
||
|
|
||
|
}) // end connected consumer
|
||
|
}) // end socket listening listener
|
||
|
|
||
|
// start it
|
||
|
await this.listen(this.path)
|
||
|
|
||
|
// if socket is terminated then shutdown gracefully
|
||
|
ON_DEATH( async () => {
|
||
|
await this.destroy()
|
||
|
})
|
||
|
|
||
|
process.once('SIGUSR2', async () => {
|
||
|
await this.destroy
|
||
|
process.kill(process.pid, 'SIGUSR2')
|
||
|
|
||
|
})
|
||
|
|
||
|
} // end create
|
||
|
|
||
|
async destroy () {
|
||
|
|
||
|
console.log('\nclosing down socket')
|
||
|
await this.close()
|
||
|
console.log('\n all connections closed....exiting')
|
||
|
process.exit()
|
||
|
|
||
|
} // end destroy
|
||
|
|
||
|
|
||
|
} // end class
|