Provide readyState for Websock objects

It mainly reports the state of the underlying object in consistent
manner.
This commit is contained in:
Pierre Ossman 2021-04-18 12:52:16 +02:00
parent 2244f53774
commit b7b7e4e26b
2 changed files with 114 additions and 6 deletions

View File

@ -71,6 +71,29 @@ export default class Websock {
} }
// Getters and Setters // Getters and Setters
get readyState() {
let subState;
if (this._websocket === null) {
return "unused";
}
subState = this._websocket.readyState;
if (ReadyStates.CONNECTING.includes(subState)) {
return "connecting";
} else if (ReadyStates.OPEN.includes(subState)) {
return "open";
} else if (ReadyStates.CLOSING.includes(subState)) {
return "closing";
} else if (ReadyStates.CLOSED.includes(subState)) {
return "closed";
}
return "unknown";
}
get sQ() { get sQ() {
return this._sQ; return this._sQ;
} }
@ -168,7 +191,7 @@ export default class Websock {
// Send Queue // Send Queue
flush() { flush() {
if (this._sQlen > 0 && ReadyStates.OPEN.indexOf(this._websocket.readyState) >= 0) { if (this._sQlen > 0 && this.readyState === 'open') {
this._websocket.send(this._encodeMessage()); this._websocket.send(this._encodeMessage());
this._sQlen = 0; this._sQlen = 0;
} }
@ -234,9 +257,7 @@ export default class Websock {
Log.Debug("<< WebSock.onopen"); Log.Debug("<< WebSock.onopen");
}; };
// If the readyState cannot be found this defaults to assuming it's not open. if (this.readyState === 'open') {
const isOpen = ReadyStates.OPEN.indexOf(this._websocket.readyState) >= 0;
if (isOpen) {
onOpen(); onOpen();
} else { } else {
this._websocket.onopen = onOpen; this._websocket.onopen = onOpen;
@ -257,8 +278,8 @@ export default class Websock {
close() { close() {
if (this._websocket) { if (this._websocket) {
if (ReadyStates.CONNECTING.indexOf(this._websocket.readyState) >= 0 || if (this.readyState === 'connecting' ||
ReadyStates.OPEN.indexOf(this._websocket.readyState) >= 0) { this.readyState === 'open') {
Log.Info("Closing WebSocket connection"); Log.Info("Closing WebSocket connection");
this._websocket.close(); this._websocket.close();
} }

View File

@ -363,6 +363,93 @@ describe('Websock', function () {
}); });
}); });
describe('ready state', function () {
it('should be "unused" after construction', function () {
let sock = new Websock();
expect(sock.readyState).to.equal('unused');
});
it('should be "connecting" if WebSocket is connecting', function () {
let sock = new Websock();
let ws = new FakeWebSocket();
ws.readyState = WebSocket.CONNECTING;
sock.attach(ws);
expect(sock.readyState).to.equal('connecting');
});
it('should be "open" if WebSocket is open', function () {
let sock = new Websock();
let ws = new FakeWebSocket();
ws.readyState = WebSocket.OPEN;
sock.attach(ws);
expect(sock.readyState).to.equal('open');
});
it('should be "closing" if WebSocket is closing', function () {
let sock = new Websock();
let ws = new FakeWebSocket();
ws.readyState = WebSocket.CLOSING;
sock.attach(ws);
expect(sock.readyState).to.equal('closing');
});
it('should be "closed" if WebSocket is closed', function () {
let sock = new Websock();
let ws = new FakeWebSocket();
ws.readyState = WebSocket.CLOSED;
sock.attach(ws);
expect(sock.readyState).to.equal('closed');
});
it('should be "unknown" if WebSocket state is unknown', function () {
let sock = new Websock();
let ws = new FakeWebSocket();
ws.readyState = 666;
sock.attach(ws);
expect(sock.readyState).to.equal('unknown');
});
it('should be "connecting" if RTCDataChannel is connecting', function () {
let sock = new Websock();
let ws = new FakeWebSocket();
ws.readyState = 'connecting';
sock.attach(ws);
expect(sock.readyState).to.equal('connecting');
});
it('should be "open" if RTCDataChannel is open', function () {
let sock = new Websock();
let ws = new FakeWebSocket();
ws.readyState = 'open';
sock.attach(ws);
expect(sock.readyState).to.equal('open');
});
it('should be "closing" if RTCDataChannel is closing', function () {
let sock = new Websock();
let ws = new FakeWebSocket();
ws.readyState = 'closing';
sock.attach(ws);
expect(sock.readyState).to.equal('closing');
});
it('should be "closed" if RTCDataChannel is closed', function () {
let sock = new Websock();
let ws = new FakeWebSocket();
ws.readyState = 'closed';
sock.attach(ws);
expect(sock.readyState).to.equal('closed');
});
it('should be "unknown" if RTCDataChannel state is unknown', function () {
let sock = new Websock();
let ws = new FakeWebSocket();
ws.readyState = 'foobar';
sock.attach(ws);
expect(sock.readyState).to.equal('unknown');
});
});
after(function () { after(function () {
// eslint-disable-next-line no-global-assign // eslint-disable-next-line no-global-assign
WebSocket = oldWS; WebSocket = oldWS;