Files
doneit-web/src/app/services/socket-connection-mcr.service.ts
T

473 lines
12 KiB
TypeScript
Raw Normal View History

2024-01-17 10:25:16 +01:00
import { Injectable } from '@angular/core';
import * as signalR from "@microsoft/signalr"
import { SessionStore } from '../store/session.service';
2024-01-29 13:49:53 +01:00
import { v4 as uuidv4 } from 'uuid'
import { HttpClient, HttpHeaders, HttpEventType } from '@angular/common/http';
import { CMAPIService } from '../shared/repository/CMAPI/cmapi.service';
import { HubConnectionBuilder } from '@microsoft/signalr';
2024-03-13 11:52:27 +01:00
import { ok, err as Err, Result } from 'neverthrow';
2024-03-27 16:04:50 +01:00
import { environment } from 'src/environments/environment';
2024-01-17 10:25:16 +01:00
@Injectable({
providedIn: 'root'
})
export class SocketConnectionMCRService {
2024-01-31 17:12:01 +01:00
// private callbacks: Function[] = []
// private onDisconnect: Function[] = []
// private onConnect: Function[] = []
2024-02-07 16:45:53 +01:00
constructor(private http: HttpClient, private _CMAPIService: CMAPIService) {
window["http"] = this.http
}
2024-01-31 17:12:01 +01:00
// connect() {
// var connection = new signalR.HubConnectionBuilder()
// .withUrl("https://gdcmapi-dev.dyndns.info/FileHub", {
// accessTokenFactory: () => "Bearer "+SessionStore.user.Authorization
// }).configureLogging(signalR.LogLevel.Information)
// .build();
// connection.on("ReceiveMessage", (message) => {
// console.log("ReceiveMessage", message)
// })
// connection.onreconnected((connectionId) => {
// console.assert(connection.state === signalR.HubConnectionState.Connected);
// console.log(`Reconnected with connectionId: ${connectionId}`);
// });
// connection.start()
// .then(() => {
// console.log("SignalR connection started.");
// })
// .catch((error) => {
// console.error("Error starting SignalR connection:", error);
// });
// connection.onclose((error) => {
// connection.start()
// console.log("SignalR connection closed:", error);
// });
// }
// subscribe(callback) {
// this.callbacks.push(callback);
// }
// unsubscribe(callback) {
// this.callbacks = this.callbacks.filter(cb => cb !== callback);
// }
// onDisconnectCallback(callback) {
// this.onDisconnect.push(callback)
// }
// onConnectCallback(callback) {
// this.onConnect.push(callback)
// }
2024-01-29 13:49:53 +01:00
}
2024-02-07 16:45:53 +01:00
class ReconnectingWebSocketSignalR {
2024-01-29 13:49:53 +01:00
2024-02-07 16:45:53 +01:00
private connection: any
isOpen: boolean = false
2024-02-02 10:50:20 +01:00
private callbacks: Function[] = []
private onDisconnect: Function[] = []
private onConnect: Function[] = []
2024-02-07 16:45:53 +01:00
private whenConnected: Function[] = []
2024-02-08 10:14:21 +01:00
stop = true
2024-01-29 13:49:53 +01:00
2024-02-07 16:45:53 +01:00
constructor() {}
2024-01-29 13:49:53 +01:00
2024-02-02 10:50:20 +01:00
connect() {
2024-02-07 16:45:53 +01:00
console.log("try to connect=================================")
2024-02-28 09:04:11 +01:00
this.stop = false;
2024-01-29 13:49:53 +01:00
2024-02-28 09:04:11 +01:00
// Limpar a conexão anterior, se existir
if (this.connection && this.connection.state !== signalR.HubConnectionState.Disconnected) {
this.connection.stop();
}
2024-02-07 16:45:53 +01:00
2024-02-28 09:04:11 +01:00
this.connection = new signalR.HubConnectionBuilder()
2024-03-27 16:04:50 +01:00
.withUrl( environment.fileHub, {
2024-02-28 09:04:11 +01:00
transport: signalR.HttpTransportType.LongPolling,
accessTokenFactory: () => SessionStore.user.Authorization
})
.configureLogging(signalR.LogLevel.Information)
.build();
2024-02-07 16:45:53 +01:00
this.connection.start()
2024-02-28 09:04:11 +01:00
.then(() => {
this.isOpen = true;
console.log('WebSocket connection established');
this.onConnect.forEach(callback => callback());
this.whenConnected.forEach(callback => callback());
}).catch((error) => {
console.error("Error starting SignalR connection:", error);
// Adicione tratamento de erros detalhado conforme necessário
// Exemplo: Verificar se o erro é devido à perda de conexão com a internet
if (error.message.includes("Failed to fetch")) {
console.error("Erro de conexão com a internet");
}
// Tentar reconectar após um atraso
if (!this.stop) {
setTimeout(() => {
this.connect();
}, 1000); // Ajuste o atraso conforme necessário
}
});
2024-01-29 13:49:53 +01:00
2024-02-28 09:04:11 +01:00
this.connection.on("ReceiveMessage", (message) => {
2024-02-07 16:45:53 +01:00
2024-02-28 09:04:11 +01:00
const data = JSON.parse(message);
2024-01-29 13:49:53 +01:00
2024-02-28 09:04:11 +01:00
console.log("ReceiveMessage", data);
2024-02-07 16:45:53 +01:00
2024-02-02 10:50:20 +01:00
this.callbacks.forEach(callback => callback(data));
2024-02-28 09:04:11 +01:00
});
2024-01-29 13:49:53 +01:00
2024-02-07 16:45:53 +01:00
this.connection.onclose((error) => {
console.log('WebSocket connection closed..');
2024-02-02 10:50:20 +01:00
this.isOpen = false;
this.onDisconnect.forEach(callback => callback());
2024-02-28 09:04:11 +01:00
// Tentar reconectar após um atraso
if (!this.stop && (!error || error.message !== "Connection stopped by client.")) {
2024-02-02 10:50:20 +01:00
setTimeout(() => {
this.connect();
2024-03-27 13:35:56 +01:00
}, 3000); // Ajuste o atraso conforme necessário
2024-02-28 09:04:11 +01:00
2024-02-02 10:50:20 +01:00
}
2024-02-07 16:45:53 +01:00
2024-01-22 16:09:02 +01:00
});
2024-02-02 10:50:20 +01:00
}
2024-01-29 13:49:53 +01:00
2024-02-09 11:26:33 +01:00
commit(path): Promise<Result<true, false>> {
2024-03-26 12:03:30 +01:00
console.log('committing')
2024-02-09 11:26:33 +01:00
return new Promise((resolve, reject) => {
2024-03-26 12:03:30 +01:00
if(this.isOpen) {
try {
console.log('this.connection.invoke', this.connection)
this.connection.invoke("CommitUpload", path).then((e) => {
console.log("commit message", e)
resolve(ok(true))
}).catch(err => {
console.error('upload catch commit error')
resolve(Err(false))
console.error(err.toString())
});
} catch(error) {
2024-03-13 11:52:27 +01:00
resolve(Err(false))
2024-03-26 12:03:30 +01:00
console.error('upload commit error')
console.error(error)
}
} else {
this.onConnect.push(()=> {
resolve(this.commit(path))
})
2024-03-13 11:52:27 +01:00
}
2024-02-09 11:26:33 +01:00
})
2024-02-02 10:50:20 +01:00
}
2024-01-29 13:49:53 +01:00
2024-02-02 10:50:20 +01:00
disconnect() {
this.stop = true
2024-02-07 16:45:53 +01:00
if(this.isOpen == true) {
this.connection.stop()
.then(() => {
console.log('WebSocket connection was closed by client');
this.isOpen = false;
this.onDisconnect.forEach(callback => callback());
console.log("SignalR connection stopped.");
})
.catch((error) => {
console.error("Error stopping SignalR connection by client:", error);
});
2024-02-02 10:50:20 +01:00
}
}
2024-01-29 13:49:53 +01:00
2024-02-02 10:50:20 +01:00
subscribe(callback) {
this.callbacks.push(callback);
}
2024-01-29 13:49:53 +01:00
2024-02-02 10:50:20 +01:00
unsubscribe(callback) {
this.callbacks = this.callbacks.filter(cb => cb !== callback);
}
2024-01-29 13:49:53 +01:00
2024-02-02 10:50:20 +01:00
onDisconnectCallback(callback) {
this.onDisconnect.push(callback)
}
onConnectCallback(callback) {
this.onConnect.push(callback)
}
2024-01-29 13:49:53 +01:00
2024-02-07 16:45:53 +01:00
registerWhenConnected(f: Function) {
if(this.isOpen) {
f();
} else {
this.whenConnected.push(f);
}
2024-01-29 13:49:53 +01:00
2024-02-07 16:45:53 +01:00
}
}
2024-01-29 13:49:53 +01:00
2024-02-07 16:45:53 +01:00
interface socketResponse {
index: string
Guid: string
IsCompleted: Boolean
}
// class ReconnectingWebSocket {
2024-01-29 13:49:53 +01:00
2024-02-07 16:45:53 +01:00
// private url: string
// private socket
// isOpen: boolean
// private callbacks: Function[] = []
// private onDisconnect: Function[] = []
// private onConnect: Function[] = []
// private whenConnected: Function[] = []
// private stop = true
// http: HttpClient = window["http"]
2024-01-29 13:49:53 +01:00
2024-02-07 16:45:53 +01:00
// constructor(url) {
// this.url = url;
// this.socket = null;
// this.isOpen = false;
// }
2024-02-01 11:44:56 +01:00
2024-02-07 16:45:53 +01:00
// connect() {
// this.socket = new WebSocket(this.url);
2024-02-01 11:44:56 +01:00
2024-02-07 16:45:53 +01:00
// this.socket.addEventListener('open', (event) => {
// this.isOpen = true;
// console.log('WebSocket connection established');
2024-01-29 13:49:53 +01:00
2024-02-07 16:45:53 +01:00
// // Example: Send a message to the server
// this.socket.send('Hello, WebSocket Server!');
// this.onConnect.forEach(callback => callback());
// this.whenConnected.forEach(callback => callback())
// });
2024-01-29 13:49:53 +01:00
2024-02-07 16:45:53 +01:00
// this.socket.addEventListener('message', (event) => {
// const data: socketResponse = JSON.parse(event.data)
// this.callbacks.forEach(callback => callback(data));
// });
2024-01-29 13:49:53 +01:00
2024-02-07 16:45:53 +01:00
// this.socket.addEventListener('close', (event) => {
// console.log('WebSocket connection closed');
// this.isOpen = false;
// this.onDisconnect.forEach(callback => callback());
// // Attempt to reconnect after a delay
// if(this.stop == false) {
// setTimeout(() => {
// this.connect();
// }, 1000); // Adjust the delay as needed
// }
// });
// }
2024-01-29 13:49:53 +01:00
2024-02-07 16:45:53 +01:00
// send(message) {
// if (this.isOpen) {
// this.socket.send(message);
// } else {
// console.error('WebSocket connection is not open. Unable to send message.');
// }
// }
2024-01-29 13:49:53 +01:00
2024-02-07 16:45:53 +01:00
// disconnect() {
// this.stop = true
// if (this.isOpen) {
// this.isOpen = false;
// this.socket.close();
// }
// }
2024-01-29 13:49:53 +01:00
2024-02-07 16:45:53 +01:00
// subscribe(callback) {
// this.callbacks.push(callback);
// }
2024-02-02 10:50:20 +01:00
2024-02-07 16:45:53 +01:00
// unsubscribe(callback) {
// this.callbacks = this.callbacks.filter(cb => cb !== callback);
// }
2024-01-29 13:49:53 +01:00
2024-02-07 16:45:53 +01:00
// onDisconnectCallback(callback) {
// this.onDisconnect.push(callback)
// }
// onConnectCallback(callback) {
// this.onConnect.push(callback)
// }
2024-01-29 13:49:53 +01:00
2024-02-07 16:45:53 +01:00
// registerWhenConnected(f: Function) {
// if(this.isOpen) {
// f();
// } else {
// this.whenConnected.push(f);
// }
2024-02-02 10:50:20 +01:00
2024-02-07 16:45:53 +01:00
// }
// }
2024-02-02 10:50:20 +01:00
// export class ObjectMergeNotification{
2024-02-07 16:45:53 +01:00
// socket = new ReconnectingWebSocket('ws://localhost:3002');
2024-02-02 10:50:20 +01:00
// callbacks: {[GUID: string]: Function} = {}
// runWatch = true
// CMAPIService: CMAPIService = window["CMAPIAPIRepository"]
// watchCount = 0
// constructor() {
// this.socket.onDisconnectCallback(()=> {
// console.log("run watch")
// this.runWatch = true
// this.watch()
// })
// this.socket.onConnectCallback(()=> {
// console.log("open trigger")
// this.runWatch = false
// })
2024-02-07 16:45:53 +01:00
2024-02-02 10:50:20 +01:00
// this.socket.subscribe((data: socketResponse) => {
// if(data.IsCompleted == true) {
// console.log("==================!!!====================")
2024-02-07 16:45:53 +01:00
// try {
2024-02-02 10:50:20 +01:00
// this.callbacks[data.Guid](data)
// delete this.callbacks[data.Guid]
// } catch (error) {}
// } else {
// console.log("else", data)
// }
// })
// this.watch()
// }
2024-02-07 16:45:53 +01:00
// connect() {
// this.socket.connect()
2024-02-02 10:50:20 +01:00
// }
// async watch() {
// this.watchCount = 0;
// if(this.runWatch) {
// setTimeout(async () => {
// for(const [key, funx] of Object.entries(this.callbacks)) {
// const request = await this.CMAPIService.getVideoHeader(key)
// if(request.isOk()) {
// funx()
// delete this.callbacks[key]
// }
// }
// this.watchCount++
// if(this.watchCount <= 15) {
2024-02-07 16:45:53 +01:00
// this.watch()
2024-02-02 10:50:20 +01:00
// } else {
// this.runWatch = false
// }
2024-02-07 16:45:53 +01:00
2024-02-02 10:50:20 +01:00
// }, 1000)
// } else {
// console.log("end loop============================")
// }
// }
2024-02-07 16:45:53 +01:00
// close() {
// this.socket.disconnect();
// this.watchCount = 0;
// this.runWatch = false
// }
2024-02-02 10:50:20 +01:00
// subscribe(GUID, callback:Function) {
// this.callbacks[GUID] = callback;
// }
// unsubscribe(GUID) {
// delete this.callbacks[GUID]
// }
// }
2024-02-07 16:45:53 +01:00
export class ObjectMergeNotification{
socket = new ReconnectingWebSocketSignalR()
callbacks: {[GUID: string]: Function} = {}
runWatch = true
CMAPIService: CMAPIService = window["CMAPIAPIRepository"]
watchCount = 0
constructor() {
2024-03-13 11:52:27 +01:00
this.socket.onDisconnectCallback(()=> {
2024-03-27 13:35:56 +01:00
//console.log("run watch")
2024-03-13 11:52:27 +01:00
this.runWatch = true
2024-03-27 13:35:56 +01:00
//this.watch()
2024-03-13 11:52:27 +01:00
})
2024-03-27 13:35:56 +01:00
this.socket.onConnectCallback(() => {
2024-03-13 11:52:27 +01:00
console.log("open trigger")
this.runWatch = false
})
2024-02-07 16:45:53 +01:00
}
connect() {
2024-03-26 12:03:30 +01:00
this.socket.connect();
2024-02-07 16:45:53 +01:00
}
close() {
2024-03-26 12:03:30 +01:00
this.socket.disconnect();
this.watchCount = 0;
this.runWatch = false
2024-02-07 16:45:53 +01:00
}
async watch() {
2024-03-26 12:03:30 +01:00
this.watchCount = 0;
2024-02-07 16:45:53 +01:00
2024-03-26 12:03:30 +01:00
if(this.runWatch) {
setTimeout(async () => {
for(const [key, funx] of Object.entries(this.callbacks)) {
2024-02-07 16:45:53 +01:00
2024-03-26 12:03:30 +01:00
const request = await this.CMAPIService.getVideoHeader(key)
2024-02-07 16:45:53 +01:00
2024-03-26 12:03:30 +01:00
if(request.isOk()) {
funx()
delete this.callbacks[key]
}
}
2024-02-07 16:45:53 +01:00
2024-03-26 12:03:30 +01:00
this.watchCount++
if(this.watchCount <= 15) {
this.watch()
} else {
this.runWatch = false
}
2024-02-07 16:45:53 +01:00
2024-03-26 12:03:30 +01:00
}, 1000)
2024-02-07 16:45:53 +01:00
2024-03-26 12:03:30 +01:00
} else {
console.log("end loop============================")
}
2024-02-07 16:45:53 +01:00
}
subscribe(GUID, callback:Function) {
this.callbacks[GUID] = callback;
}
unsubscribe(GUID) {
delete this.callbacks[GUID]
}
}