diff --git a/example/daemon/www/js/connection_view.js b/example/daemon/www/js/connection_view.js index a1f36b6..9b7c6e2 100644 --- a/example/daemon/www/js/connection_view.js +++ b/example/daemon/www/js/connection_view.js @@ -29,6 +29,14 @@ export class ConnectionView { const authenticateBox = document.createElement("div"); this.element.appendChild(authenticateBox); + const authLabel = document.createElement("span"); + authLabel.textContent = "use authentication:"; + authenticateBox.appendChild(authLabel); + + this.authenticateCheckbox = document.createElement("input"); + this.authenticateCheckbox.type = "checkbox"; + authenticateBox.appendChild(this.authenticateCheckbox); + const usernameLabel = document.createElement("span"); usernameLabel.textContent = "user:"; authenticateBox.appendChild(usernameLabel); @@ -46,12 +54,6 @@ export class ConnectionView { this.passwordTextbox.type = "password"; this.passwordTextbox.value = "secret"; authenticateBox.appendChild(this.passwordTextbox); - - this.authenticateButton = document.createElement("input"); - this.authenticateButton.type = "button"; - this.authenticateButton.value = "authenticate"; - this.authenticateButton.addEventListener("click", () => { this._onAuthenticateButtonClicked(); }); - authenticateBox.appendChild(this.authenticateButton); } _onConnectButtonClicked() { @@ -66,15 +68,22 @@ export class ConnectionView { _onAuthenticateButtonClicked() { if (this._client.isConnected()) { - const username = this.usernameTextbox.value; - const password = this.passwordTextbox.value; - this._client.authenticate("username", { username, password }); } } _onConnectionOpened() { - this._client.addProvider("test", this._provider); + if (this.authenticateCheckbox.checked) { + console.log("authenticate"); + const username = this.usernameTextbox.value; + const password = this.passwordTextbox.value; + + const promise = this._client.authenticate("username", { username, password }); + promise.then(() => { this._client.addProvider("test", this._provider) }); + } else { + this._client.addProvider("test", this._provider); + } + this.connectButton.value = "disconnect"; } diff --git a/example/daemon/www/js/webfuse/client.js b/example/daemon/www/js/webfuse/client.js index 31deab3..e3a8cf6 100644 --- a/example/daemon/www/js/webfuse/client.js +++ b/example/daemon/www/js/webfuse/client.js @@ -5,6 +5,8 @@ export class Client { constructor(provider) { this._provider = { }; + this._pendingRequests = {}; + this._id = 0; this._ws = null; this.onopen = () => { }; this.onclose = () => { }; @@ -24,14 +26,20 @@ export class Client { }; } - authenticate(type, credentials) { - const request = { - "method": "authenticate", - "params": [type, credentials], - "id": 42 - }; + _invokeRequest(method, params) { + const id = ++this._id; + const request = {method, params, id}; + + return new Promise((resolve, reject) => { + this._pendingRequests[id] = {resolve, reject}; + this._ws.send(JSON.stringify(request)); + }) - this._ws.send(JSON.stringify(request)); + + } + + authenticate(type, credentials) { + return this._invokeRequest("authenticate", [type, credentials]); } addProvider(name, provider) { @@ -56,27 +64,61 @@ export class Client { return ((this._ws) && (this._ws.readyState === WebSocket.OPEN)); } + _isRequest(request) { + const method = request.method; + + return (("string" === typeof(method)) && (request.hasOwnProperty("params"))); + } + + _isResponse(response) { + const id = response.id; + + return (("number" === typeof(id)) && (response.hasOwnProperty("result") || response.hasOwnProperty("error"))); + } + + _removePendingRequest(id) { + let result = null; + + if (this._pendingRequests.hasOwnProperty(id)) { + result = this._pendingRequests[id]; + delete this._pendingRequests[id]; + } + + return result; + } + _onmessage(message) { try { - const request = JSON.parse(message.data); - const method = request.method; - const id = request.id; - const params = request.params; + const data = JSON.parse(message.data); - if ("string" !== typeof(method)) { - throw new Error("parse error: missing field: \"method\""); + if (this._isRequest(data)) { + const method = data.method; + const id = data.id; + const params = data.params; + + if ("number" === typeof(id)) { + this._invoke(method, params, id); + } + else { + this._notify(method, params); + } + } + else if (this._isResponse(data)) { + const id = data.id; + const result = data.result; + const error = data.error; + + const request = this._removePendingRequest(id); + if (request) { + if (result) { + request.resolve(result); + } + else { + request.reject(error); + } + } } - if (!params) { - throw new Error("parse error: missing field: \"params\""); - } - - if ("number" === typeof(request.id)) { - this._invoke(method, params, id); - } - else { - this._notify(method, params); - } } catch (ex) { // swallow