File:LoggingService.js
(function()
{
/**
* Remote loggging of events
* @class LoggingService
* @constructor
* @param {string} [remoteHost] The hostname or IP Address of the machine
* to log out the event data through WebSocket connection.
* @param {string} [remotePort=1025] The port for remote logging using
* a WebSocket connection.
* @param {String} [channel] The name of the channel to start session.
*/
var LoggingService = function(remoteHost, remotePort, channel)
{
/**
* The Web socket connection for remote logging
* @property {WebSocket|MozWebSocket} socket
* @private
*/
this.socket = null;
/**
* If the web socket connection is available for sending
* @property {boolean} connected
* @private
*/
this.connected = false;
/**
* If the web socket connection is trying to connect
* @property {boolean} connecting
* @private
*/
this.connecting = false;
/**
* The collection of events to buffer while connecting
* @property {array} socketBuffer
* @private
*/
this.socketBuffer = [];
/**
* The current channel for remote logging
* @property {string} _channel
* @private
*/
this._channel = null;
// Connect to the remote host if it's specified
if (remoteHost)
{
this.connect(remoteHost, remotePort);
// Set the channel
if (channel)
{
this.channel = channel;
}
}
};
var p = LoggingService.prototype;
/**
* Connect to the remote logging app
* @method connect
* @param {string} host Either the IP address or host
* @param {int} [port=1025] The port to use for remote logging.
*/
p.connect = function(host, port)
{
// Make sure WebSocket exists without prefixes for us
if (("WebSocket" in window || "MozWebSocket" in window) && host)
{
port = port || 1025;
window.WebSocket = WebSocket || MozWebSocket;
// Bind handlers
var onCloseRemote = this._onCloseRemote.bind(this);
var onOpenRemote = this._onOpenRemote.bind(this);
// Close the current connection if there is one
onCloseRemote();
// Start the connection
this.connecting = true;
try
{
var s = this.socket = new WebSocket("ws://" + host + ":" + port);
s.onopen = onOpenRemote;
s.onclose = onCloseRemote;
s.onerror = onCloseRemote;
return true;
}
catch (error)
{
onCloseRemote();
if (DEBUG) console.error("Unable to connect to WebSocket");
return false;
}
}
return false;
};
/**
* The remote logging connection has been created
* @method onOpenRemote
* @private
*/
p._onOpenRemote = function()
{
this.connecting = false;
this.connected = true;
// Flush all buffered events once we're connected
for (var i = 0; i < this.socketBuffer.length; i++)
{
this.socket.send(this.socketBuffer[i]);
}
// Clear the buffer
this.socketBuffer.length = 0;
};
/**
* Callback for when the websocket is closed
* @method onCloseRemote
* @private
*/
p._onCloseRemote = function()
{
this.connecting = this.connected = false;
if (this.socketBuffer)
{
this.socketBuffer.length = 0;
}
if (this.socket)
{
this.socket.close();
this.socket.onopen = null;
this.socket.onmessage = null;
this.socket.onclose = null;
this.socket.onerror = null;
this.socket = null;
}
};
/**
* Set the current channel
* @property {String} channel
*/
Object.defineProperty(p, 'channel',
{
set: function(channel)
{
this._channel = channel;
this.send('session');
},
get: function()
{
return this._channel;
}
});
/**
* Send data to the remote logging application
* @method send
* @param {string} type Either "event" or "session"
* @param {object} data The data object to send
*/
p.send = function(type, data)
{
var event = {
type: type,
channel: this._channel
};
if (!!data)
{
event.data = data;
}
// Convert to string to send
event = JSON.stringify(event);
if (this.connecting)
{
this.socketBuffer.push(event);
}
else if (this.connected)
{
this.socket.send(event);
}
};
/**
* Don't use after this
* @method destroy
*/
p.destroy = function()
{
this._onCloseRemote();
this.socketBuffer = null;
};
namespace('springroll.pbskids').LoggingService = LoggingService;
}());