summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2021-04-18 12:52:16 +0200
committerPierre Ossman <ossman@cendio.se>2021-04-18 14:26:05 +0200
commitb7b7e4e26b1f93f56471419f5b6ca5069fd1e4b2 (patch)
tree50b687b38025f496cf9bff304e7a014e27051cc1
parent2244f5377433e2107ca3fce4934939a7b4600dc4 (diff)
downloadnovnc-b7b7e4e26b1f93f56471419f5b6ca5069fd1e4b2.tar.gz
Provide readyState for Websock objects
It mainly reports the state of the underlying object in consistent manner.
-rw-r--r--core/websock.js33
-rw-r--r--tests/test.websock.js87
2 files changed, 114 insertions, 6 deletions
diff --git a/core/websock.js b/core/websock.js
index 89ccdd9..52e27be 100644
--- a/core/websock.js
+++ b/core/websock.js
@@ -71,6 +71,29 @@ export default class Websock {
}
// 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() {
return this._sQ;
}
@@ -168,7 +191,7 @@ export default class Websock {
// Send Queue
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._sQlen = 0;
}
@@ -234,9 +257,7 @@ export default class Websock {
Log.Debug("<< WebSock.onopen");
};
- // If the readyState cannot be found this defaults to assuming it's not open.
- const isOpen = ReadyStates.OPEN.indexOf(this._websocket.readyState) >= 0;
- if (isOpen) {
+ if (this.readyState === 'open') {
onOpen();
} else {
this._websocket.onopen = onOpen;
@@ -257,8 +278,8 @@ export default class Websock {
close() {
if (this._websocket) {
- if (ReadyStates.CONNECTING.indexOf(this._websocket.readyState) >= 0 ||
- ReadyStates.OPEN.indexOf(this._websocket.readyState) >= 0) {
+ if (this.readyState === 'connecting' ||
+ this.readyState === 'open') {
Log.Info("Closing WebSocket connection");
this._websocket.close();
}
diff --git a/tests/test.websock.js b/tests/test.websock.js
index 196a300..1c2aa13 100644
--- a/tests/test.websock.js
+++ b/tests/test.websock.js
@@ -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 () {
// eslint-disable-next-line no-global-assign
WebSocket = oldWS;