|
|
@@ -1,8 +1,10 @@
|
|
|
import * as SocketIO from "socket.io";
|
|
|
import {Interfaces} from "./Interfaces";
|
|
|
+import {Conversations} from "./Conversation";
|
|
|
|
|
|
|
|
|
export namespace Clients {
|
|
|
+
|
|
|
interface MessagingClientData {
|
|
|
id: string;
|
|
|
name: string;
|
|
|
@@ -14,7 +16,7 @@ export namespace Clients {
|
|
|
}
|
|
|
|
|
|
export class NullManager implements Interfaces.ClientsManagerInterface {
|
|
|
- get(id: string): Promise<Interfaces.ClientInterface> {
|
|
|
+ get(id: string, refresh: boolean = false): Promise<Interfaces.ClientInterface> {
|
|
|
return new Promise((resolve, reject) => {
|
|
|
reject("NullManger can't return client")
|
|
|
});
|
|
|
@@ -40,10 +42,14 @@ export namespace Clients {
|
|
|
private create(id: string): Promise<Interfaces.ClientInterface> {
|
|
|
return new Promise((resolve, reject) => {
|
|
|
this.apiConnector.execute('/user', {id: id, action: 'getinfo'}).then((response: string) => {
|
|
|
- let data = JSON.parse(response);
|
|
|
- this.clients[id] = new Client(this.apiConnector, this, this.conversationsManager, this.logger, data);
|
|
|
- resolve(this.clients[id]);
|
|
|
- }).catch(reject);
|
|
|
+ try {
|
|
|
+ let data = JSON.parse(response);
|
|
|
+ this.clients[id] = new Client(this.apiConnector, this, this.conversationsManager, this.logger, data);
|
|
|
+ resolve(this.clients[id]);
|
|
|
+ } catch (err) {
|
|
|
+ reject(err);
|
|
|
+ }
|
|
|
+ }, reject);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
@@ -58,7 +64,7 @@ export namespace Clients {
|
|
|
this.clients[data.id] = client;
|
|
|
this.clients[data.id].addSocket(socket);
|
|
|
setStatus(this.clients[data.id], this.logger);
|
|
|
- }).catch((error: Error) => {
|
|
|
+ }, (error: Error) => {
|
|
|
console.log(error.message);
|
|
|
});
|
|
|
} else {
|
|
|
@@ -67,22 +73,40 @@ export namespace Clients {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- get(id: string): Promise<Interfaces.ClientInterface> {
|
|
|
+ get(id: string, refresh: boolean = false): Promise<Interfaces.ClientInterface> {
|
|
|
this.logger.debug(`Get client with ID=${id}`);
|
|
|
return new Promise((resolve, reject) => {
|
|
|
- if (this.clients[id] !== undefined) {
|
|
|
+ if (this.clients[id] !== undefined && !refresh) {
|
|
|
this.logger.debug(`Client with ID=${id} is in list of clients`);
|
|
|
resolve(this.clients[id]);
|
|
|
} else {
|
|
|
this.logger.debug(`Load client with ID=${id} by API call`);
|
|
|
this.create(id).then((client: Client) => {
|
|
|
resolve(client);
|
|
|
- }).catch(reject);
|
|
|
+ }, reject);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ export class SocketMessage {
|
|
|
+ private _eventName: string;
|
|
|
+ private _data: {};
|
|
|
+
|
|
|
+ constructor(eventName: string, data: {} = {}) {
|
|
|
+ this._eventName = eventName;
|
|
|
+ this._data = data;
|
|
|
+ }
|
|
|
+
|
|
|
+ get eventName(): string {
|
|
|
+ return this._eventName;
|
|
|
+ }
|
|
|
+
|
|
|
+ get data(): {} {
|
|
|
+ return this._data;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
export class Client implements Interfaces.ClientInterface {
|
|
|
private sockets: SocketIO.Socket[] = [];
|
|
|
private clientId;
|
|
|
@@ -93,6 +117,7 @@ export namespace Clients {
|
|
|
private logger: Interfaces.LoggerInterface;
|
|
|
private conversationsManager: Interfaces.ConversationsManagerInterface;
|
|
|
private clientsManager: Interfaces.ClientsManagerInterface;
|
|
|
+ private messageQueue: SocketMessage[] = [];
|
|
|
|
|
|
protected api: Interfaces.ApiConnectorInterface;
|
|
|
|
|
|
@@ -142,6 +167,28 @@ export namespace Clients {
|
|
|
this.payedTime = parseInt(data.payedTime);
|
|
|
this.timeToPay = data.timeToPay;
|
|
|
this._coefficient = parseInt(data.coefficient);
|
|
|
+ setInterval(this.releaseQueue.bind(this), 10000);
|
|
|
+ }
|
|
|
+
|
|
|
+ private releaseQueue() {
|
|
|
+ for (let i in this.messageQueue) {
|
|
|
+ if (this.messageQueue.hasOwnProperty(i)) {
|
|
|
+ this.sendToSockets(this.messageQueue[i].eventName, this.messageQueue[i].data);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private sendToSockets(event: string, data: {} = {}) {
|
|
|
+ this.logger.debug(`Send event "${event}" to client with ID=${this.id}`);
|
|
|
+ for (let i in this.sockets) {
|
|
|
+ if (this.sockets.hasOwnProperty(i)) {
|
|
|
+ (function (i) {
|
|
|
+ setTimeout(() => {
|
|
|
+ this.sockets[i].emit(event, data)
|
|
|
+ }, 0);
|
|
|
+ }).bind(this)(i);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
addSocket(socket: SocketIO.Socket) {
|
|
|
@@ -154,17 +201,14 @@ export namespace Clients {
|
|
|
socket.on('chat-accept-conversation', this.onAcceptConversation.bind(this));
|
|
|
socket.on('chat-run-conversation', this.onRunConversation.bind(this));
|
|
|
socket.on('chat-send-message', this.onSendMessage.bind(this));
|
|
|
+ socket.on('chat-stop-conversation', this.onStopConversation.bind(this));
|
|
|
}
|
|
|
|
|
|
send(event: string, data: {} = {}) {
|
|
|
- for (let i in this.sockets) {
|
|
|
- if (this.sockets.hasOwnProperty(i)) {
|
|
|
- (function (i) {
|
|
|
- setTimeout(() => {
|
|
|
- this.sockets[i].emit(event, data)
|
|
|
- }, 0);
|
|
|
- }).bind(this)(i);
|
|
|
- }
|
|
|
+ if (this.sockets.length > 0) {
|
|
|
+ this.sendToSockets(event, data);
|
|
|
+ } else {
|
|
|
+ this.messageQueue.push(new SocketMessage(event, data));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -182,7 +226,7 @@ export namespace Clients {
|
|
|
this.status = false;
|
|
|
for (let id in this.conversations) {
|
|
|
if (this.conversations.hasOwnProperty(id)) {
|
|
|
- this.logger.debug(`Pause ${id}`);
|
|
|
+ this.logger.debug(`Pause conversation with ID=${id} because client with ID=${this.id} is disconnected`);
|
|
|
this.conversations[id].state = Interfaces.ConversationState.PAUSED();
|
|
|
}
|
|
|
}
|
|
|
@@ -240,9 +284,16 @@ export namespace Clients {
|
|
|
|
|
|
private onRunConversation(...args) {
|
|
|
let data = args[0];
|
|
|
- this.conversationsManager.get(data.id).then(conversation => {
|
|
|
+ this.conversationsManager.get(data.id).then((conversation: Interfaces.ConversationInterface) => {
|
|
|
conversation.state = Interfaces.ConversationState.RUNNING();
|
|
|
});
|
|
|
}
|
|
|
+
|
|
|
+ private onStopConversation(...args) {
|
|
|
+ let data = args[0];
|
|
|
+ this.conversationsManager.get(data.id).then((conversation: Interfaces.ConversationInterface) => {
|
|
|
+ conversation.state = Interfaces.ConversationState.STOPPED();
|
|
|
+ });
|
|
|
+ }
|
|
|
}
|
|
|
}
|