strolch-wc-ws-observer/strolch-wc-ws-observer.html

205 lines
7.4 KiB
HTML

<link rel="import" href="../polymer/polymer.html">
<dom-module id="strolch-wc-ws-observer">
<template>
</template>
<script>
'use strict';
// shared state
var initialized = false;
var webSocket = null;
var observers = {};
var registrations = {};
Polymer({
is: 'strolch-wc-ws-observer',
behaviors: [],
properties: {
wsPath: {
type: String,
value: '/websocket/strolch'
}
},
attached: function (e) {
console.log("strolch-wc-ws-observer attached, connecting WebSocket");
if (!initialized) {
initialized = true;
this._openWebSocket();
}
},
register: function (objectType, type, source, params, callback) {
var byObjectType = observers[objectType];
if (byObjectType == null) {
observers[objectType] = {};
byObjectType = observers[objectType]
}
var byType = byObjectType[type];
if (byType == null) {
byObjectType[type] = {};
byType = byObjectType[type];
this._register(objectType, type, params);
}
if (byType[source] != null) {
console.error("There already is a callback defined for " + objectType + " " + type + " " + source + ". Overwriting!");
}
byType[source] = callback;
console.log("Registered callback for " + objectType + " " + type + " " + source + " params: " + JSON.stringify(params));
},
unregister: function (objectType, type, source) {
var byObjectType = observers[objectType];
if (byObjectType == null) {
return;
}
var byType = byObjectType[type];
if (byType == null) {
return
}
delete byType[source];
console.log("Unregistered callback for " + objectType + " " + type + " " + source);
},
_reRegister: function () {
var objectTypes = Object.keys(observers);
console.log("Reregistering " + objectTypes.length + " object types...");
for (var i = 0; i < objectTypes.length; i++) {
var objectType = objectTypes[i];
var byType = observers[objectTypes[i]];
var types = Object.keys(byType);
console.log("Reregistering " + types.length + " types...");
for (var j = 0; j < types.length; j++) {
var type = types[i];
var params = registrations[objectType + "_" + type];
this._register(objectType, type, params);
}
}
},
_register: function (objectType, type, params) {
console.log("Registering for updates for " + objectType + " " + type);
registrations[objectType + "_" + type] = params;
this._sendWsMessage({
msgType: "ObserverRegister",
objectType: objectType,
type: type,
params: params
});
},
notifyObservers: function (msg) {
var byObjectType = observers[msg.objectType];
if (byObjectType == null)
return;
var byType = byObjectType[msg.type];
if (byType == null) {
byType = byObjectType["*"];
if (byType == null)
return;
}
Object.keys(byType).forEach(function (k) {
try {
byType[k](msg.msgType, msg.objectType, msg.type, msg.data);
} catch (e) {
console.error("Failed to update " + k + " for " + msg.objectType + " " + msg.type + ": " + e);
console.error(e);
}
});
},
_openWebSocket: function () {
var url;
if (window.location.protocol === 'https:') {
url = "wss://"
} else {
url = "ws://"
}
url += window.location.hostname + ':' + window.location.port + this.wsPath;
console.log("Connecting to WS URL " + url);
webSocket = new WebSocket(url);
var that = this;
webSocket.onclose = function (evt) {
that.webSocket = null;
that._handleSocketError('WebSocket connection to server lost due to: ' + evt.reason);
};
webSocket.onopen = function (event) {
console.log('Socket opened, sending auth...');
var msg = {
msgType: "Authenticate",
username: Strolch.getUserConfig().username,
authToken: Strolch.getAuthToken()
};
that._sendWsMessage(msg);
};
webSocket.onmessage = function (event) {
that._handleSocketMessage(event.data);
};
webSocket.onerror = function (event) {
console.error('WebSocket Received error from socket:');
console.error(event.data);
};
},
_handleSocketError: function (message) {
if (message.indexOf('Invalid authentication') >= 0) {
console.error("Authentication invalid. Not reconnecting WebSocket");
} else {
console.error('Received error from socket: ' + message);
console.log("Reconnecting...");
this.debounce("reconnect", this._reconnectWebSocket, 500);
}
},
_handleSocketMessage: function (data) {
var msg = JSON.parse(data);
if (msg.msgType == "ObserverAdd" || msg.msgType == "ObserverUpdate" || msg.msgType == "ObserverRemove") {
this.notifyObservers(msg);
} else if (msg.msgType == "Authenticate") {
console.log("Successfully authenticated, re-registering...");
this._reRegister();
} else {
console.error("Unhandled event " + msg.msgType);
}
},
_sendWsMessage: function (data) {
console.log(webSocket.readyState);
if (webSocket.readyState != 1) {
var that = this;
console.log("Delaying message as WebSocket not yet ready!");
setTimeout(function () {
that._sendWsMessage(data);
}, 100);
} else {
webSocket.send(JSON.stringify(data));
}
},
_reconnectWebSocket: function (msg) {
this._openWebSocket();
}
});
</script>
</dom-module>