comparison src/implab/messaging/Session.js @ 0:fc2517695ee1

Initial commit, draft import of existing work
author cin
date Thu, 01 Jun 2017 13:20:03 +0300
parents
children 7d7059d2a810
comparison
equal deleted inserted replaced
-1:000000000000 0:fc2517695ee1
1 define(
2 [
3 "dojo/_base/declare",
4 "dojo/_base/lang",
5 "dojo/request",
6 "./Destination",
7 "dojo/Evented",
8 "dojo/Deferred",
9 "../_LogMixin" ],
10
11 function(declare, lang, request, Destination, Evented, Deferred, _LogMixin) {
12
13 var cls = declare(
14 [ Evented, _LogMixin ],
15 {
16 _id : null,
17 _baseUrl : null,
18 _destinations : null,
19 _timeout : 100000,
20 _clients : null,
21 _started : null,
22 _starting : false,
23
24 constructor : function(baseUrl, options) {
25 if (!baseUrl)
26 throw new Error("baseUrl is required");
27 options = options || {};
28
29 this._baseUrl = baseUrl.replace(/\/*$/, "");
30 this._destinations = {};
31 this._pending = [];
32 this._clients = {};
33 if (options.timeout)
34 this._timeout = options.timeout;
35
36 this._started = new Deferred();
37 },
38
39 start : function() {
40 if (this._starting)
41 return this._started;
42 this._starting = true;
43
44 var me = this;
45 me.log("START");
46 request(this._baseUrl, {
47 method : "POST",
48 handleAs : "json"
49 }).then(function(result) {
50 me._id = result;
51 me._emitConnected();
52 me._poll();
53 me._started.resolve(me);
54 }, function(error) {
55 me._emitError(error);
56 me._started.reject(me);
57 });
58 return me._started.promise;
59 },
60
61 createClient : function(options) {
62 if (!options || !options.destination || !options.mode)
63 throw new Error("Invalid argument");
64
65 var me = this;
66
67 return me._started
68 .then(function() {
69 var url = me._makeUrl(me._id);
70 me.log(
71 "CREATE mode=${0}, destination=${1}",
72 options.mode,
73 options.destination);
74
75 return request(url, {
76 method : "POST",
77 data : {
78 mode : options.mode,
79 destination : options.destination
80 },
81 handleAs : 'json'
82 })
83 .then(
84 function(id) {
85 me
86 .log(
87 "CLIENT id=${0}, mode=${1}, destination=${2}",
88 id,
89 options.mode,
90 options.destination);
91 me._clients[id] = options.client
92 ? options.client
93 : function(msg) {
94 me
95 .warn(
96 "The client id=${0}, mode=${1}, destination=${2} isn't accepting mesages",
97 id,
98 options.mode,
99 options.destination);
100 };
101 return id;
102 });
103 });
104
105 },
106
107 deleteClient : function(options) {
108 if (!options || !options.clientId)
109 throw new Error("Invalid argument");
110
111 var me = this, id = options.clientId;
112
113 return me._started.then(function() {
114 var url = me._makeUrl(me._id, options.clientId);
115
116 me.log("DELETE CLIENT ${0}", options.clientId);
117
118 return request(url, {
119 method : "DELETE",
120 handleAs : 'json'
121 }).then(function() {
122 me.log("CLIENT DELETED ${0}", options.clientId);
123 me._clients[id] = undefined;
124 });
125 });
126 },
127
128 _poll : function() {
129 var me = this, url = this._makeUrl(this._id);
130 me.log("POLL timeout=${0}", me._timeout);
131 request(url, {
132 method : "GET",
133 handleAs : "json",
134 query : {
135 timeout : me._timeout
136 }
137 }).then(function(response) {
138 me._handlePoll(response);
139 me._poll();
140 }, function(err) {
141 me.error("POLL faield with ${0}", err);
142 me._emitError(err);
143 });
144 },
145
146 _handlePoll : function(response) {
147 if (!response) {
148 this.log("POLL response undefined, looks like a bug");
149 return;
150 }
151 if (!response.results || !response.results.length) {
152 this.log("POLL response is empty");
153 return;
154 }
155
156 var results = response.results;
157 this.log("POLL got ${0} results", results.length);
158
159 for (var i = 0; i < results.length; i++) {
160 var result = results[i];
161 var client = this._clients[result.clientId];
162 if (!client) {
163 // TODO this could happen due to client isn't
164 // registered yet
165 this.error("Unknown client ${0}", result.clientId);
166 continue;
167 }
168 client.call(this, result);
169 }
170 },
171
172 _emitError : function(err) {
173 this.emit("error", err);
174 },
175
176 _emitConnected : function() {
177 var me = this;
178 me.log("CONNECTED");
179 me.emit("connected");
180 },
181
182 _makeUrl : function() {
183 var parts = [ this._baseUrl ];
184 for (var i = 0; i < arguments.length; i++)
185 parts.push(arguments[i].replace(/\/*$/, ""));
186 return parts.join('/');
187 },
188
189 queue : function(name) {
190 return this._getDestination("queue://" + name);
191 },
192
193 topic : function(name) {
194 return this._getDestination("topic://" + name);
195 },
196
197 _getDestination : function(uri) {
198 if (uri in this._destinations)
199 return this._destinations[uri];
200
201 var dest = new Destination(this, uri);
202 this._destinations[uri] = dest;
203 return dest;
204 },
205
206 toString : function() {
207 return [ "[", "SESSION ", this._id, "]" ].join(" ");
208 }
209 });
210
211 cls.connect = function(url, options) {
212 var session = new cls(url, options);
213 return session.start();
214 };
215
216 return cls;
217 });