You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
HMG_QLine/lib/repositories/signalR_repo.dart

111 lines
4.0 KiB
Dart

import 'dart:developer';
import 'dart:io';
import 'package:hmg_qline/services/logger_service.dart';
import 'package:hmg_qline/utilities/enums.dart';
import 'package:http/io_client.dart';
import 'package:hmg_qline/constants/app_constants.dart';
import 'package:signalr_core/signalr_core.dart';
abstract class SignalrRepo {
Future<bool?> startHubConnection({
required String deviceIp,
required Function(List<Object?>?) onHubTicketCall,
required Function(dynamic) onHubConfigCall,
required Function(dynamic) onHubConnecting,
required Function(dynamic) onHubReconnected,
required Function(dynamic) onHubDisconnected,
});
}
class SignalrRepoImp implements SignalrRepo {
HubConnection? connection;
LoggerService loggerService;
SignalrRepoImp({this.connection, required this.loggerService});
@override
Future<bool?> startHubConnection({
required String deviceIp,
required Function(List<Object?>?) onHubTicketCall,
required Function(dynamic) onHubConfigCall,
required Function(dynamic) onHubConnecting,
required Function(dynamic) onHubReconnected,
required Function(dynamic) onHubDisconnected,
}) async {
try {
String hubBaseURL = ApiConstants.baseUrlHub;
if ((connection != null) && (connection!.state == HubConnectionState.connected || connection!.state == HubConnectionState.connecting)) {
return true;
}
connection = HubConnectionBuilder()
.withUrl(
"$hubBaseURL?IPAddress=$deviceIp",
HttpConnectionOptions(
client: IOClient(HttpClient()..badCertificateCallback = (x, y, z) => true),
logging: (level, message) => log(message),
))
.withAutomaticReconnect()
.build();
connection!.serverTimeoutInMilliseconds = 120000;
int reconnectAttempts = 0;
const int maxReconnectAttempts = 10;
const Duration reconnectDelay = Duration(seconds: 5);
connection!.onclose((exception) async {
log(exception.toString());
onHubDisconnected(exception);
// Attempt to reconnect with limit and delay
if (reconnectAttempts < maxReconnectAttempts) {
reconnectAttempts++;
loggerService.logToFile("SignalR reconnect attempt #$reconnectAttempts", type: LogTypeEnum.data);
await Future.delayed(reconnectDelay);
try {
await connection!.start();
loggerService.logToFile("SignalR reconnected after disconnect", type: LogTypeEnum.data);
reconnectAttempts = 0; // Reset on success
} catch (e) {
loggerService.logError("Reconnect failed: $e");
}
} else {
loggerService.logError("Max SignalR reconnect attempts reached.");
}
});
connection!.onreconnecting((exception) => onHubConnecting(exception));
connection!.onreconnected((connectionId) {
log(connectionId.toString());
onHubReconnected(connectionId);
});
connection!.on(ApiConstants.sendQLinePatientCall, (List<Object?>? message) {
onHubTicketCall(message);
});
connection!.on(ApiConstants.sendQLineConfig, (List<Object?>? message) {
onHubConfigCall(message);
});
await connection!.start();
return true;
} catch (e) {
loggerService.logError(e.toString());
loggerService.logToFile(e.toString(), type: LogTypeEnum.error);
return false;
}
}
bool getHubConnectionState() {
if (connection == null) return false;
log("connectionState: ${connection!.state}");
if (connection!.state == HubConnectionState.connected || connection!.state == HubConnectionState.connecting) return true;
if (connection!.state == HubConnectionState.disconnected || connection!.state == HubConnectionState.disconnecting) return false;
return false;
}
closeConnection() async {
if (connection!.state == HubConnectionState.connected || connection!.state == HubConnectionState.connecting) {
await connection!.stop();
}
}
}