/**
* @ngdoc service
* @name WebSocket
* @module s4c.services.websocket
*
* @description Componente para acesso a api do backend e/ou comunicação entre controllers
*
*
*/
(function () {
'use strict';
/*
* Incidentes:
* * newIncidente
* * newCategoria
* Mensageria:
* * newMessage(USER)
* * newGroup
* * newGroupMessage
*/
/**
* @method WebSocket_s4c
* @param {*} AuthService
* @param {*} $rootScope
* @param {*} $q
*/
function WebSocket_s4c(AuthService, $rootScope, $q) {
/**
* @method WebsocketIO
* @param {*} url
*/
function WebsocketIO(url) {
if (url !== undefined && url !== null) {
this.url = url;
} else {
this.url = (window.location.protocol === "https:" ? "wss" : "ws") + "://" + window.location.host +
"/" + window.location.pathname.split("/")[1];
}
this.ws = null;
this.messages = {};
this.aliasCount = 1;
this.remoteListeners = { "#WSIO#addListener": "0000" };
this.localListeners = { "0000": "#WSIO#addListener" };
this._bytesWritten = 0;
Object.defineProperty(this, "bytesRead", {
get: function () {
return this._bytesRead;
}
});
this._bytesRead = 0;
Object.defineProperty(this, "bytesWritten", {
get: function () {
return this._bytesWritten;
}
});
/**
* @method open
* @param {*} callback
*/
this.open = function (callback) {
var _this = this;
console.log('WebsocketIO> open', this.url);
this.ws = new WebSocket(this.url);
this.ws.binaryType = "arraybuffer";
this.ws.onopen = callback;
// Handler when a message arrives
this.ws.onmessage = function (message) {
var fName;
// text message
if (typeof message.data === "string") {
// update the bytes read value
_this._bytesRead += message.data.length;
// decode the message
var msg = JSON.parse(message.data);
fName = _this.localListeners[msg.f];
if (fName === undefined) {
console.log('WebsocketIO> No handler for message');
}
if (fName === "#WSIO#addListener") {
_this.remoteListeners[msg.d.listener] = msg.d.alias;
return;
}
_this.messages[fName](msg.d);
} else {
// update the bytes read value
_this._bytesRead += message.data.byteLength;
// decode the message
var uInt8 = new Uint8Array(message.data);
var func = String.fromCharCode(uInt8[0]) +
String.fromCharCode(uInt8[1]) +
String.fromCharCode(uInt8[2]) +
String.fromCharCode(uInt8[3]);
fName = _this.localListeners[func];
var buffer = uInt8.subarray(4, uInt8.length);
_this.messages[fName](buffer);
}
};
// triggered by unexpected close event
this.ws.onclose = function (evt) {
console.log("WebsocketIO> socket closed");
if ('close' in _this.messages) {
_this.messages.close(evt);
}
};
};
/**
* @method on
* @param name
* @param callback
*/
this.on = function (name, callback) {
var alias = ("0000" + this.aliasCount.toString(16)).substr(-4);
this.localListeners[alias] = name;
this.messages[name] = callback;
this.aliasCount++;
if (name === "close") {
return;
}
this.emit('#WSIO#addListener', { listener: name, alias: alias });
};
/**
* @method emit
* @param name
* @param data
*/
this.emit = function (name, data, attempts) {
if (name === null || name === "") {
console.log("Error: no message name specified");
return;
}
var _this = this;
var message;
var alias = this.remoteListeners[name];
if (alias === undefined) {
if (attempts === undefined) {
attempts = 16;
}
if (attempts >= 0) {
setTimeout(function () {
_this.emit(name, data, attempts - 1);
}, 4);
} else {
console.log("Warning: not sending message, recipient has no listener (" + name + ")");
}
return;
}
// send binary data as array buffer
if (data instanceof Uint8Array) {
// build an array with the name of the function
var funcName = new Uint8Array(4);
funcName[0] = alias.charCodeAt(0);
funcName[1] = alias.charCodeAt(1);
funcName[2] = alias.charCodeAt(2);
funcName[3] = alias.charCodeAt(3);
message = new Uint8Array(4 + data.length);
// copy the name of the function first
message.set(funcName, 0);
// then copy the payload
message.set(data, 4);
// send the message using websocket
this.ws.send(message.buffer);
// update property
this._bytesWritten += message.buffer.byteLength;
} else {
// send data as JSON string
message = JSON.stringify({ f: alias, d: data });
this.ws.send(message);
// update property
this._bytesWritten += message.length;
}
};
/**
* Deliberate close function
*
* @method close
*/
this.close = function () {
// disable onclose handler first
this.ws.onclose = function () { };
// then close
this.ws.close();
};
}
function getCookie(sKey) {
if (!sKey) {
return null;
}
return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" +
encodeURIComponent(sKey).replace(/[-.+*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1"))
|| null;
}
var wsio;
function start() {
// Connect to the server
wsio = new WebsocketIO('wss://172.17.0.90:9090');
console.log("Connected to server: ", window.location.origin);
// Get the cookie for the session, if there's one
//var session = getCookie("session");
// Callback when socket opens
wsio.open(function () {
console.log("open websocket");
// Register to the server as a console
var clientDescription = {
clientType: "MultivisManagerTeste",
requests: {
config: true,
version: true,
time: false,
console: true
},
session: ""
};
wsio.emit('addClient', clientDescription);
});
}
function emit(channel, data) {
wsio.emit(channel, data);
}
function on(channel, cb) {
wsio.on(channel, cb);
}
function removeListener(channel) {
wsio.removeListener(channel);
}
return {
emit: emit,
on: on,
start: start,
removeListener: removeListener
};
}
angular.module('s4c.services.WebSocket', [])
.factory('WebSocket', WebSocket_s4c);
WebSocket_s4c.$inject = ['AuthService', '$rootScope', '$q'];
}());