socket-class.js
now emits 'socket' on socket listening state
added stop method to stop socket listening manually.  (no remote access via base yet)
added .name and .id to consumer from either packet props or packet data prop
consumer.js
  don't allow passed options mutation
  add .name prop
  merge in passed data option prop into authentication packet sent to socket
master
David Kebler 2020-01-14 13:38:24 -08:00
parent 8a4fdf067c
commit 65169e3ded
3 changed files with 37 additions and 11 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "@uci/socket", "name": "@uci/socket",
"version": "0.2.29", "version": "0.2.30",
"description": "JSON packet intra(named)/inter(TCP) host communication over socket", "description": "JSON packet intra(named)/inter(TCP) host communication over socket",
"main": "src", "main": "src",
"scripts": { "scripts": {

View File

@ -26,9 +26,11 @@ class SocketConsumer extends Socket {
* @param {object} [opts={}] test * @param {object} [opts={}] test
*/ */
constructor(opts = {}) { constructor(options = {}) {
super() super()
const opts = Object.assign({},options) // don't allow mutation
this.id = opts.id || opts.name || 'socket:' + new Date().getTime() this.id = opts.id || opts.name || 'socket:' + new Date().getTime()
this.name = opts.name || 'a socket consumer'
log = logger({ log = logger({
file: 'src/consumer.js', file: 'src/consumer.js',
class: 'Consumer', class: 'Consumer',
@ -64,13 +66,15 @@ class SocketConsumer extends Socket {
this._reconnectCount = 0 this._reconnectCount = 0
this._connected = false this._connected = false
this._authenticated = false this._authenticated = false
this._active = false
this._connection = 'offline' this._connection = 'offline'
this._first = true // first connection or not this._first = true // first connection or not
this._pingTimeout // value sent from socket upon connect this._pingTimeout // value sent from socket upon connect
} }
get connected() { return this._connected} get connected() { return this._connected}
get active() { return !!this._authenticated } // FIXME change active
get active() { return this._authenticated }
get connection() { return this._connection } get connection() { return this._connection }
notify(state, moreOpts={}) { notify(state, moreOpts={}) {
@ -215,7 +219,6 @@ class SocketConsumer extends Socket {
this.stream = func this.stream = func
} }
// PRIVATE METHODS // PRIVATE METHODS
// default authentication using a simple token // default authentication using a simple token
@ -286,9 +289,8 @@ async function handshake (packet) {
if (packet._handshake) { if (packet._handshake) {
this._connected = true this._connected = true
this.notify('handshake') this.notify('handshake')
let authPacket = this._authenticate() || {} const authPacket = Object.assign(this._authenticate() || {}, {_authenticate:true, data:this._data})
authPacket._authenticate = true // console.log('----------------authentication packet---------------',authPacket)
authPacket.data = this._data
let res = await this._authenticateSend(authPacket) let res = await this._authenticateSend(authPacket)
this.stream.removeAllListeners('message') this.stream.removeAllListeners('message')
clearTimeout(this._doneAuthenticate) clearTimeout(this._doneAuthenticate)

View File

@ -88,6 +88,7 @@ export default function socketClass(Server) {
* @returns {type} Description * @returns {type} Description
*/ */
async create() { async create() {
this.emit('socket',{state:'creating', msg:'creating socket for consumers to connect'})
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
_ON_DEATH(async () => { _ON_DEATH(async () => {
log.error({method:'create', line:84, msg:'\nhe\'s dead jim'}) log.error({method:'create', line:84, msg:'\nhe\'s dead jim'})
@ -131,17 +132,23 @@ export default function socketClass(Server) {
this.errors.push(err) this.errors.push(err)
if(this.errorCount>2 && this.errorCount<6) { if(this.errorCount>2 && this.errorCount<6) {
let errors= {level:'warn',msg:'something bad maybe going on, 3 errors', errors:this.errors} let errors= {level:'warn',msg:'something bad maybe going on, 3 errors', errors:this.errors}
this.emit('socket',{state:'error', msg:'2 to 5 socket errors', errors:this.errors})
this.emit('log', errors) this.emit('log', errors)
log.error(errors) log.error(errors)
} }
if(this.errorCount>5) { if(this.errorCount>5) {
let errors = {level:'fatal',msg:'something fatal is going on, 6 errors', errors:this.errors} let errors = {level:'fatal',msg:'something fatal is going on, 6 errors', errors:this.errors}
log.fatal(errors) log.fatal(errors)
this.removeAllListeners('listening')
this.listening=false this.listening=false
this.close(() => {
this.emit('socket',{state:'offline', msg:'too many socket errors no longer listening for consumers to connect'})
})
this.emit('log', errors) this.emit('log', errors)
} }
}) })
let msg = `socket ready and listening ${typeof this.address() ==='string' ? `at ${this.address()}` : `on port ${this.address().port}`}` let msg = `socket ready and listening ${typeof this.address() ==='string' ? `at ${this.address()}` : `on port ${this.address().port}`}`
this.emit('socket',{state:'listening', msg:msg})
let obj = {method:'create', line:54, msg:msg} let obj = {method:'create', line:54, msg:msg}
log.info(obj) log.info(obj)
this.on('connection', this._connectionHandler.bind(this)) this.on('connection', this._connectionHandler.bind(this))
@ -155,6 +162,17 @@ export default function socketClass(Server) {
}) // end creeate promise }) // end creeate promise
} // end create } // end create
async stop() {
return new Promise(function(resolve) {
this.removeAllListeners('listening')
this.listening=false
this.close(() => {
this.emit('socket',{state:'offline', msg:'manually closed socket on request'})
resolve('socket is offline')
})
})
}
/** /**
* registerPacketProcessor - Description * registerPacketProcessor - Description
* @public * @public
@ -263,18 +281,24 @@ export default function socketClass(Server) {
else { else {
let [err, res] = await btc(this._authenticate)(packet) let [err, res] = await btc(this._authenticate)(packet)
consumer.authenticated = this.allowAnonymous ? 'anonymous' : (err ? false : res) consumer.authenticated = this.allowAnonymous ? 'anonymous' : (err ? false : res)
consumer.data = packet.data consumer.data = packet.data || {}
consumer.name = packet.name || consumer.data.name
consumer.id = packet.id || consumer.data.id
// console.log('-------------------Inbound Consumer Authenticated---------------------------')
// console.log(packet)
// console.log(consumer.authenticated, consumer.name,consumer.id,consumer.data)
// console.log('--------------------------------------------------------')
packet.authenticated = consumer.authenticated packet.authenticated = consumer.authenticated
packet.reason = err || null packet.reason = err || null
log.debug({msg:'sending authorization result to consumer', packet:packet}) log.debug({msg:'sending authorization result to consumer', packet:packet})
await this._send(consumer,packet) // send either way await this._send(consumer,packet) // send either way
if (err && !this.allowAnonymous) { if (err && !this.allowAnonymous) {
log.info({msg:`consumer ${consumer.data.name} authentication failed`, consumer:consumer.data, consumer_sid:consumer.sid, reason:err}) log.info({msg:`consumer ${consumer.data.name} authentication failed`, name:consumer.name, id:consumer.id, data:consumer.data, consumer_sid:consumer.sid, reason:err})
reject(packet.reason) reject(packet.reason)
} }
else { else {
log.info({msg:`consumer ${consumer.data.name} authenticated successfuly`, consumer:consumer.data}) log.info({msg:`consumer ${consumer.name} authenticated successfuly`, name:consumer.name, id:consumer.id, data:consumer.data})
if (this.allowAnonymous) log.warn({msg:`consumer ${consumer.data.name}, connected anonymously`, consumer:consumer.data}) if (this.allowAnonymous) log.warn({msg:`consumer ${consumer.data.name}, connected anonymously`})
resolve(consumer.authenticated) resolve(consumer.authenticated)
} }
} }