You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
By clicking “Sign up for GitHub”, you agree to our
terms of service
and
privacy statement
. We’ll occasionally send you account related emails.
Already on GitHub?
Sign in
to your account
function close(code,reason) {
debug('[Auth Phase] closing',code, reason)
removeListeners.call(this)
reject(`closed, reason:${reason}, code:${code}`)
emit like this
ws.close(1000,'test')
Expected result:
reason to have a value that was passed/emitted
Actual result:
code is 1000 but reason is undefined not
test
kinda scratching my head. I thought one can ONLY have a single argument for a listener handler. Thus one needs to pass an object, array, buffer, string whatever but only one when emitting, but ws's close method INSISTS that first argument be a number. Ok then it should still combine code and reason into single argument before emitting the close event right?
I would expect something more like this to be emitted {code:10, reason:'some string'} like in this issue which you said was wrong.
#1373
Please read the documentation:
https://github.com/websockets/ws/blob/master/doc/ws.md#event-close-1
https://github.com/websockets/ws/blob/master/doc/ws.md#websocketclosecode-reason
Here is an example to further clarify.
ws/test/websocket.test.js
Lines 1476 to 1490
91b5173
yes of course I read that documentation that's how I knew I could emit both a reason along with a code.
So isn't my
ws.on('close'
code just like your test?
Correct me if I am wrong
It passes a function with two arguments. I emit with two arguments the second being a string and
reason
the second end up undefined. The difference to your example is
I have a named handler as I must later remove it
I bind a context (the socket in this case) to my handler so I can call another function (a remove listener) in the handler.
possibly this is why the
reason
argument is undefined for me?
Below is the complete context in which the
close
listener is created and the close event is emitting via .close. In both the debug statement and in the rejection string value
reason
is undefined in the close handler
const MSG_TYPE_AUTH_REQUIRED = 'auth_required'
const MSG_TYPE_AUTH_INVALID = 'auth_invalid'
const MSG_TYPE_AUTH_OK = 'auth_ok'
function createSocket (opts) {
return new Promise((resolve, reject) => {
if (!opts.hassUrl) {
throw ha.ERR_HASS_HOST_REQUIRED
const auth = JSON.stringify({
type: 'auth',
access_token: opts.access_token
let url = `${opts.hassUrl}/${opts.wssPath || 'api/websocket'}`
debug('[Auth Phase] Initializing', url)
setTimeout(() => reject(new Error('Unable to Authorize in 5 seconds')),5000)
let ws = new WebSocket(url,opts)
function removeListeners() {
debug('[Auth Phase] removing authorization listeners')
this.removeAllListeners('message',authorize)
this.removeAllListeners('error', error)
this.removeAllListeners('close', close)
ws.on('error', error.bind(ws))
function error(err) {
debug('[Auth Phase] socket error', err)
this.close()
ws.on('close', close.bind(ws))
// close handler accepting two arguments code,reason
function close(code,reason) {
debug('[Auth Phase] closing',code, reason)
removeListeners.call(this)
reject(`closed, reason:${reason}, code:${code}`)
ws.on('message',authorize.bind(ws))
function authorize(event) {
const message = JSON.parse(event)
debug('[Auth Phase] Message Received', message)
switch (message.type) {
case MSG_TYPE_AUTH_REQUIRED:
try {
debug('[Auth Phase] sending authorization\n',auth)
this.send(auth)
} catch (err) {
debug('sending auth error')
// close and emit a close event
this.close(1000,`sending authorization error: ${err}`)
break
case MSG_TYPE_AUTH_OK:
removeListeners.call(ws)
resolve(this)
break
case MSG_TYPE_AUTH_INVALID:
// close and emit a close event
this.close(1000,MSG_TYPE_AUTH_INVALID)
break
default:
debug('[Auth Phase] Unhandled message', message)
// close and emit a close event
this.close(1000,`unhandled authorization error, ${message}`)
} // end authorize
} // end createSocket
console showing missing value for reason
home-assistant:ws [Auth Phase] closing 1000 +10ms
home-assistant:ws [Auth Phase] removing authorization listeners +1ms
home-assistant:ws socket create error closed, reason:, code:1000 +0ms
FATAL: UNABLE TO START SYSTEM!
closed, reason:, code:1000
The close code and reason is read from the close frame which is sent by the other peer. In your example you are sending it from the client socket to the server.
If you want a close reason on the client you have to send that reason from the server.
Also in your example you don't need to bind the listeners. Listeners are, by default, called with the emitter that emits the event as context.
Thx for your input. I had success using the w3c client of this module https://www.npmjs.com/package/websocket and since it returns an event object to the close listener handler I can get both code and reason key values no problem using .close method. reason
must make the round trip if what you say is true. Why not for your module?
const MSG_TYPE_AUTH_INVALID = 'auth_invalid'
ws.onclose = close
function close(event) {
debug('[Auth Phase] closing',event.code, event.reason)
removeListeners.call(this)
reject(`closed, reason:${event.reason}, code:${event.code}`)
ws.close(1000,MSG_TYPE_AUTH_INVALID)
[Auth Phase] closing 1000 auth_invalid +13ms