|
|
define(
|
|
|
[
|
|
|
"dojo/_base/declare",
|
|
|
"dojo/_base/lang",
|
|
|
"dojo/request",
|
|
|
"./Destination",
|
|
|
"dojo/Evented",
|
|
|
"dojo/Deferred",
|
|
|
"../log/_LogMixin" ],
|
|
|
|
|
|
function(declare, lang, request, Destination, Evented, Deferred, _LogMixin) {
|
|
|
|
|
|
var cls = declare(
|
|
|
[ Evented, _LogMixin ],
|
|
|
{
|
|
|
_id : null,
|
|
|
_baseUrl : null,
|
|
|
_destinations : null,
|
|
|
_timeout : 100000,
|
|
|
_clients : null,
|
|
|
_started : null,
|
|
|
_starting : false,
|
|
|
|
|
|
constructor : function(baseUrl, options) {
|
|
|
if (!baseUrl)
|
|
|
throw new Error("baseUrl is required");
|
|
|
options = options || {};
|
|
|
|
|
|
this._baseUrl = baseUrl.replace(/\/*$/, "");
|
|
|
this._destinations = {};
|
|
|
this._pending = [];
|
|
|
this._clients = {};
|
|
|
if (options.timeout)
|
|
|
this._timeout = options.timeout;
|
|
|
|
|
|
this._started = new Deferred();
|
|
|
},
|
|
|
|
|
|
start : function() {
|
|
|
if (this._starting)
|
|
|
return this._started;
|
|
|
this._starting = true;
|
|
|
|
|
|
var me = this;
|
|
|
me.log("START");
|
|
|
request(this._baseUrl, {
|
|
|
method : "POST",
|
|
|
handleAs : "json"
|
|
|
}).then(function(result) {
|
|
|
me._id = result;
|
|
|
me._emitConnected();
|
|
|
me._poll();
|
|
|
me._started.resolve(me);
|
|
|
}, function(error) {
|
|
|
me._emitError(error);
|
|
|
me._started.reject(me);
|
|
|
});
|
|
|
return me._started.promise;
|
|
|
},
|
|
|
|
|
|
createClient : function(options) {
|
|
|
if (!options || !options.destination || !options.mode)
|
|
|
throw new Error("Invalid argument");
|
|
|
|
|
|
var me = this;
|
|
|
|
|
|
return me._started
|
|
|
.then(function() {
|
|
|
var url = me._makeUrl(me._id);
|
|
|
me.log(
|
|
|
"CREATE mode=${0}, destination=${1}",
|
|
|
options.mode,
|
|
|
options.destination);
|
|
|
|
|
|
return request(url, {
|
|
|
method : "POST",
|
|
|
data : {
|
|
|
mode : options.mode,
|
|
|
destination : options.destination
|
|
|
},
|
|
|
handleAs : 'json'
|
|
|
})
|
|
|
.then(
|
|
|
function(id) {
|
|
|
me
|
|
|
.log(
|
|
|
"CLIENT id=${0}, mode=${1}, destination=${2}",
|
|
|
id,
|
|
|
options.mode,
|
|
|
options.destination);
|
|
|
me._clients[id] = options.client
|
|
|
? options.client
|
|
|
: function(msg) {
|
|
|
me
|
|
|
.warn(
|
|
|
"The client id=${0}, mode=${1}, destination=${2} isn't accepting mesages",
|
|
|
id,
|
|
|
options.mode,
|
|
|
options.destination);
|
|
|
};
|
|
|
return id;
|
|
|
});
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
deleteClient : function(options) {
|
|
|
if (!options || !options.clientId)
|
|
|
throw new Error("Invalid argument");
|
|
|
|
|
|
var me = this, id = options.clientId;
|
|
|
|
|
|
return me._started.then(function() {
|
|
|
var url = me._makeUrl(me._id, options.clientId);
|
|
|
|
|
|
me.log("DELETE CLIENT ${0}", options.clientId);
|
|
|
|
|
|
return request(url, {
|
|
|
method : "DELETE",
|
|
|
handleAs : 'json'
|
|
|
}).then(function() {
|
|
|
me.log("CLIENT DELETED ${0}", options.clientId);
|
|
|
me._clients[id] = undefined;
|
|
|
});
|
|
|
});
|
|
|
},
|
|
|
|
|
|
_poll : function() {
|
|
|
var me = this, url = this._makeUrl(this._id);
|
|
|
me.log("POLL timeout=${0}", me._timeout);
|
|
|
request(url, {
|
|
|
method : "GET",
|
|
|
handleAs : "json",
|
|
|
query : {
|
|
|
timeout : me._timeout
|
|
|
}
|
|
|
}).then(function(response) {
|
|
|
me._handlePoll(response);
|
|
|
me._poll();
|
|
|
}, function(err) {
|
|
|
me.error("POLL faield with ${0}", err);
|
|
|
me._emitError(err);
|
|
|
});
|
|
|
},
|
|
|
|
|
|
_handlePoll : function(response) {
|
|
|
if (!response) {
|
|
|
this.log("POLL response undefined, looks like a bug");
|
|
|
return;
|
|
|
}
|
|
|
if (!response.results || !response.results.length) {
|
|
|
this.log("POLL response is empty");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
var results = response.results;
|
|
|
this.log("POLL got ${0} results", results.length);
|
|
|
|
|
|
for (var i = 0; i < results.length; i++) {
|
|
|
var result = results[i];
|
|
|
var client = this._clients[result.clientId];
|
|
|
if (!client) {
|
|
|
// TODO this could happen due to client isn't
|
|
|
// registered yet
|
|
|
this.error("Unknown client ${0}", result.clientId);
|
|
|
continue;
|
|
|
}
|
|
|
client.call(this, result);
|
|
|
}
|
|
|
},
|
|
|
|
|
|
_emitError : function(err) {
|
|
|
this.emit("error", err);
|
|
|
},
|
|
|
|
|
|
_emitConnected : function() {
|
|
|
var me = this;
|
|
|
me.log("CONNECTED");
|
|
|
me.emit("connected");
|
|
|
},
|
|
|
|
|
|
_makeUrl : function() {
|
|
|
var parts = [ this._baseUrl ];
|
|
|
for (var i = 0; i < arguments.length; i++)
|
|
|
parts.push(arguments[i].replace(/\/*$/, ""));
|
|
|
return parts.join('/');
|
|
|
},
|
|
|
|
|
|
queue : function(name) {
|
|
|
return this._getDestination("queue://" + name);
|
|
|
},
|
|
|
|
|
|
topic : function(name) {
|
|
|
return this._getDestination("topic://" + name);
|
|
|
},
|
|
|
|
|
|
_getDestination : function(uri) {
|
|
|
if (uri in this._destinations)
|
|
|
return this._destinations[uri];
|
|
|
|
|
|
var dest = new Destination(this, uri);
|
|
|
this._destinations[uri] = dest;
|
|
|
return dest;
|
|
|
},
|
|
|
|
|
|
toString : function() {
|
|
|
return [ "[", "SESSION ", this._id, "]" ].join(" ");
|
|
|
}
|
|
|
});
|
|
|
|
|
|
cls.connect = function(url, options) {
|
|
|
var session = new cls(url, options);
|
|
|
return session.start();
|
|
|
};
|
|
|
|
|
|
return cls;
|
|
|
});
|
|
|
|