205 lines
7.4 KiB
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> |