|
|
@@ -1,9 +1,7 @@
|
|
|
-/**
|
|
|
- * Created by lcdee on 19.04.2017.
|
|
|
- */
|
|
|
|
|
|
import {Client} from "./Client";
|
|
|
import * as SocketIO from "socket.io";
|
|
|
+import {Conversation} from "./Conversation";
|
|
|
|
|
|
export class App {
|
|
|
private clients: ClientsContainer = new ClientsContainer(this);
|
|
|
@@ -27,26 +25,24 @@ export class App {
|
|
|
console.log(`Server started at ${config.host}:${config.port}`);
|
|
|
}
|
|
|
|
|
|
- getClient(id: string): Client {
|
|
|
- try {
|
|
|
- return this.clients.get(id);
|
|
|
- } catch (e) {
|
|
|
- console.log(e.message);
|
|
|
- }
|
|
|
+ getClient(id: string): Promise<Client> {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ if (this.clients.get(id) !== undefined) {
|
|
|
+ resolve(this.clients.get(id));
|
|
|
+ } else {
|
|
|
+ this.apiCall('/user', {id: id, action: 'getinfo'}).then((response: string) => {
|
|
|
+ let data = JSON.parse(response);
|
|
|
+ this.clients[data.id] = new Client(this, data);
|
|
|
+ resolve(this.clients.get(id));
|
|
|
+ }).catch(reject)
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
addClient(socket: SocketIO.Socket, data: {} = {}) {
|
|
|
this.clients.add(socket, data);
|
|
|
}
|
|
|
|
|
|
- removeClient(id: string) {
|
|
|
- try {
|
|
|
- this.clients.remove(id);
|
|
|
- } catch (e) {
|
|
|
- console.log(e.message);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
addConversation(conversation: Conversation) {
|
|
|
this.conversations[conversation.id] = conversation;
|
|
|
}
|
|
|
@@ -55,26 +51,54 @@ export class App {
|
|
|
delete this.conversations[id];
|
|
|
}
|
|
|
|
|
|
- apiCall(path: string, data: any, success: (data?: string) => void = () => {
|
|
|
- }, fail: (err?: string) => void = () => {
|
|
|
- }) {
|
|
|
- let client = require('http').request({
|
|
|
- host: 'galapsy.ru',
|
|
|
- port: 80,
|
|
|
- path: '/api' + path,
|
|
|
- method: 'POST'
|
|
|
- }, (response) => {
|
|
|
- let responseMessage = '';
|
|
|
- response.on('data', (chunk) => {
|
|
|
- responseMessage += chunk;
|
|
|
- }).on('end', () => {
|
|
|
- success(responseMessage);
|
|
|
- }).on('error', (err) => {
|
|
|
- fail(err);
|
|
|
+ getConversation(id: number): Promise<Conversation> {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ if (this.conversations.hasOwnProperty(id)) {
|
|
|
+ resolve(this.conversations[id]);
|
|
|
+ } else {
|
|
|
+ this.apiCall('/conversations', {action: 'get', id: id}).then((response: string) => {
|
|
|
+ let data = JSON.parse(response);
|
|
|
+ let conversation = new Conversation(this);
|
|
|
+ conversation.duration = parseInt(data.duration);
|
|
|
+ conversation.id = data.id;
|
|
|
+ this.getClient(data.initiatorId).then(client => {
|
|
|
+ conversation.initiator = client;
|
|
|
+ this.getClient(data.recipientId).then(client => {
|
|
|
+ conversation.recipient = client;
|
|
|
+ if (data.isStarted == 1 && data.isFinished == 0) {
|
|
|
+ conversation.state = Conversation.STATE_RUNNING;
|
|
|
+ }
|
|
|
+ this.conversations[id] = conversation;
|
|
|
+ resolve(this.conversations[id]);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }).catch(err => {
|
|
|
+ reject(err);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ apiCall(path: string, data: any): Promise<string> {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ let client = require('http').request({
|
|
|
+ host: 'galapsy.ru',
|
|
|
+ port: 80,
|
|
|
+ path: '/api' + path,
|
|
|
+ method: 'POST'
|
|
|
+ }, response => {
|
|
|
+ let responseMessage = '';
|
|
|
+ response.on('data', (chunk) => {
|
|
|
+ responseMessage += chunk;
|
|
|
+ }).on('end', () => {
|
|
|
+ resolve(responseMessage);
|
|
|
+ }).on('error', (err) => {
|
|
|
+ reject(err);
|
|
|
+ });
|
|
|
});
|
|
|
+ client.write(JSON.stringify(data));
|
|
|
+ client.end();
|
|
|
});
|
|
|
- client.write(JSON.stringify(data));
|
|
|
- client.end();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -98,12 +122,13 @@ class ClientsContainer {
|
|
|
|
|
|
add(socket: SocketIO.Socket, data) {
|
|
|
if (!this.clients.hasOwnProperty(data.id)) {
|
|
|
- this.app.apiCall('/user', {id: data.id, action: 'getinfo'}, response => {
|
|
|
- let data = JSON.parse(response);
|
|
|
- this.clients[data.id] = new Client(this.app, data);
|
|
|
- this.clients[data.id].addSocket(socket);
|
|
|
- this.app.apiCall('/user', {id: data.id, action: 'setstatus', value: true});
|
|
|
- });
|
|
|
+ this.app.apiCall('/user', {id: data.id, action: 'getinfo'})
|
|
|
+ .then((response: string) => {
|
|
|
+ let data = JSON.parse(response);
|
|
|
+ this.clients[data.id] = new Client(this.app, data);
|
|
|
+ this.clients[data.id].addSocket(socket);
|
|
|
+ this.app.apiCall('/user', {id: data.id, action: 'setstatus', value: true});
|
|
|
+ });
|
|
|
} else {
|
|
|
this.clients[data.id].addSocket(socket);
|
|
|
}
|
|
|
@@ -113,132 +138,10 @@ class ClientsContainer {
|
|
|
if (this.clients !== undefined && this.clients[id] !== undefined) {
|
|
|
return this.clients[id];
|
|
|
}
|
|
|
- throw new Error(`Client ${id} not found`);
|
|
|
- }
|
|
|
-
|
|
|
- remove(id: string) {
|
|
|
- if (this.clients !== undefined && this.clients[id] !== undefined) {
|
|
|
- delete this.clients[id];
|
|
|
- } else {
|
|
|
- throw new Error(`Client ${id} not found`);
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
-export class Conversation {
|
|
|
- private app: App;
|
|
|
- private interval;
|
|
|
- private syncInterval;
|
|
|
-
|
|
|
- id: string;
|
|
|
- initiator: Client;
|
|
|
- recipient: Client;
|
|
|
-
|
|
|
- duration: number = 0;
|
|
|
-
|
|
|
- conversationState: (value?: number) => number;
|
|
|
-
|
|
|
- static readonly STATE_INIT = 0;
|
|
|
- static readonly STATE_RUNNING = 1;
|
|
|
- static readonly STATE_STOPPED = 2;
|
|
|
- static readonly STATE_PAUSED = 3;
|
|
|
-
|
|
|
- constructor(app: App) {
|
|
|
- let state;
|
|
|
- this.app = app;
|
|
|
- this.conversationState = (value?: number) => {
|
|
|
- if (value !== undefined)
|
|
|
- state = value;
|
|
|
- return state;
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
- init(success: (response) => void, fail: (err) => void) {
|
|
|
- this.app.apiCall('/conversations', {'action': 'create'}, success, fail);
|
|
|
- }
|
|
|
-
|
|
|
- set state(value: number) {
|
|
|
- if ([Conversation.STATE_INIT, Conversation.STATE_RUNNING, Conversation.STATE_PAUSED, Conversation.STATE_STOPPED].indexOf(value) === -1) {
|
|
|
- throw new Error(`State ${value} not in list of possible values.`);
|
|
|
- }
|
|
|
- this.conversationState(value);
|
|
|
- if (value === Conversation.STATE_INIT) {
|
|
|
- this.app.conversations[this.id] = this;
|
|
|
- this.initiator.conversations[this.id] = this;
|
|
|
- this.recipient.conversations[this.id] = this;
|
|
|
- }
|
|
|
- if (value === Conversation.STATE_RUNNING) {
|
|
|
- let lastIntervalTick = Date.now();
|
|
|
- this.interval = setInterval(() => {
|
|
|
- let now = Date.now();
|
|
|
- let interval = (now - lastIntervalTick) / 1000;
|
|
|
- this.duration += interval;
|
|
|
- lastIntervalTick = now;
|
|
|
- this.initiator.payedTime -= Math.ceil(interval * this.recipient.coeficient);
|
|
|
- this.recipient.payedTime += Math.ceil(interval * this.recipient.coeficient);
|
|
|
- if (this.initiator.payedTime < 0) {
|
|
|
- this.state = Conversation.STATE_STOPPED;
|
|
|
- }
|
|
|
- }, 1000);
|
|
|
- this.syncInterval = setInterval(() => {
|
|
|
- this.initiator.send('chat-sync-timer', {
|
|
|
- conversationId: this.id,
|
|
|
- duration: this.duration
|
|
|
- });
|
|
|
- this.recipient.send('chat-sync-timer', {
|
|
|
- conversationId: this.id,
|
|
|
- duration: this.duration
|
|
|
- });
|
|
|
- this.app.apiCall('/conversations', {
|
|
|
- id: this.id,
|
|
|
- action: 'duration',
|
|
|
- duration: this.duration
|
|
|
- });
|
|
|
- this.app.apiCall('/user', {
|
|
|
- action: 'updatetime',
|
|
|
- id: this.initiator.id,
|
|
|
- value: this.initiator.payedTime
|
|
|
- });
|
|
|
- this.app.apiCall('/user', {
|
|
|
- action: 'updatetime',
|
|
|
- id: this.recipient.id,
|
|
|
- value: this.recipient.payedTime
|
|
|
- });
|
|
|
- }, 5000);
|
|
|
- this.app.apiCall('/conversations', {id: this.id, action: 'start'});
|
|
|
- }
|
|
|
- if (value === Conversation.STATE_STOPPED || value === Conversation.STATE_PAUSED) {
|
|
|
- clearInterval(this.interval);
|
|
|
- clearInterval(this.syncInterval);
|
|
|
- }
|
|
|
- if (value === Conversation.STATE_STOPPED) {
|
|
|
- delete this.initiator.conversations[this.id];
|
|
|
- delete this.recipient.conversations[this.id];
|
|
|
- delete this.app.conversations[this.id];
|
|
|
- this.app.apiCall('/conversations', {id: this.id, action: 'stop', duration: this.duration});
|
|
|
- this.app.apiCall('/user', {
|
|
|
- action: 'updatetime',
|
|
|
- id: this.initiator.id,
|
|
|
- value: this.initiator.payedTime
|
|
|
- });
|
|
|
- this.app.apiCall('/user', {
|
|
|
- action: 'updatetime', id:
|
|
|
- this.recipient.id,
|
|
|
- value: this.recipient.payedTime
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- get state() {
|
|
|
- return this.conversationState();
|
|
|
- }
|
|
|
-
|
|
|
- newMessage(message) {
|
|
|
- this.initiator.sendMessage({message: message, duration: this.duration});
|
|
|
- this.recipient.sendMessage({message: message, duration: this.duration});
|
|
|
- }
|
|
|
-}
|
|
|
|
|
|
export interface AppConfigInterface {
|
|
|
host?: string;
|