in src/index.js [110:169]
_setupListeners() {
this._socket.addEventListener('message', async event => {
try {
// When we receive data from the channelserver, pump it through the TLS connection
// to decrypt it, then echo it back out to consumers as an event.
const channelServerEnvelope = JSON.parse(event.data);
const payload = await this._connection.recv(base64urlToBytes(channelServerEnvelope.message));
if (payload !== null) {
const data = JSON.parse(bytesToUtf8(payload));
this.dispatchEvent(new CustomEvent('message', {
detail: {
data,
sender: channelServerEnvelope.sender,
},
}));
}
} catch (error) {
let event;
// The underlying TLS connection will signal a clean shutdown of the channel
// by throwing a special error, because it doesn't really have a better
// signally mechanism available.
if (error instanceof TLSCloseNotify) {
this._peerClosed = true;
if (this._selfClosed) {
this._shutdown();
}
event = new CustomEvent('close');
} else {
event = new CustomEvent('error', {
detail: {
error,
}
});
}
this.dispatchEvent(event);
}
});
// Relay the WebSocket events.
this._socket.addEventListener('error', () => {
this._shutdown();
// The dispatched event that we receive has no useful information.
this.dispatchEvent(new CustomEvent('error', {
detail: {
error: new Error('WebSocket error.'),
},
}));
});
// In TLS, the peer has to explicitly send a close notification,
// which we dispatch above. Unexpected socket close is an error.
this._socket.addEventListener('close', () => {
this._shutdown();
if (! this._peerClosed) {
this.dispatchEvent(new CustomEvent('error', {
detail: {
error: new Error('WebSocket unexpectedly closed'),
}
}));
}
});
}