100 lines
2.6 KiB
Dart
100 lines
2.6 KiB
Dart
import 'dart:async';
|
|
import 'dart:io';
|
|
|
|
import 'package:fcs/config.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:logging/logging.dart';
|
|
import 'package:connectivity_plus/connectivity_plus.dart';
|
|
|
|
import 'api_helper.dart';
|
|
|
|
enum ConnectivityStatus { none, online }
|
|
|
|
class NetworkConnectivity {
|
|
final log = Logger('NetworkConnectivity');
|
|
|
|
static final NetworkConnectivity instance = NetworkConnectivity._internal();
|
|
static String _hostName = "";
|
|
static ConnectivityStatus? _currentResult;
|
|
|
|
NetworkConnectivity._internal() {
|
|
_initialise();
|
|
var uri = Uri.parse(Config.instance.apiURL);
|
|
_hostName = uri.host;
|
|
log.info("host name:$_hostName");
|
|
}
|
|
|
|
Connectivity connectivity = Connectivity();
|
|
|
|
final StreamController<ConnectivityStatus> _controller =
|
|
StreamController.broadcast();
|
|
|
|
Stream<ConnectivityStatus> get statusStream => _controller.stream;
|
|
|
|
Timer? _checkTimer;
|
|
void _initialise() async {
|
|
await _checkStatus(await connectivity.checkConnectivity());
|
|
|
|
connectivity.onConnectivityChanged.listen((result) {
|
|
if (_currentResult == null) {
|
|
_checkStatus(result);
|
|
} else {
|
|
_checkTimer?.cancel();
|
|
_checkTimer = Timer(const Duration(seconds: 7), () {
|
|
_checkTimer?.cancel();
|
|
_checkStatus(result);
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
Future<void> _checkStatus(List<ConnectivityResult> result) async {
|
|
bool isOnline = false;
|
|
if (!result.contains(ConnectivityResult.none) && !kIsWeb) {
|
|
try {
|
|
final hostNameLookup = await InternetAddress.lookup(_hostName);
|
|
if (hostNameLookup.isNotEmpty &&
|
|
hostNameLookup[0].rawAddress.isNotEmpty) {
|
|
if (await checkHeartbeat()) {
|
|
isOnline = true;
|
|
}
|
|
} else {
|
|
isOnline = false;
|
|
}
|
|
isOnline = true;
|
|
} on Exception catch (_) {
|
|
isOnline = false;
|
|
}
|
|
}
|
|
_addStream(isOnline || kIsWeb
|
|
? ConnectivityStatus.online
|
|
: ConnectivityStatus.none);
|
|
}
|
|
|
|
Future<bool> checkHeartbeat() async {
|
|
try {
|
|
var result = await requestAPI("/hb", "GET");
|
|
var status = result["status"];
|
|
if (status != null && status != "") {
|
|
return true;
|
|
}
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void disposeStream() => _controller.close();
|
|
|
|
_addStream(ConnectivityStatus? updateResult) async {
|
|
if (updateResult == null) return;
|
|
if (updateResult == _currentResult) return;
|
|
_currentResult = updateResult;
|
|
|
|
if (!_controller.isClosed) {
|
|
log.info("sink: $_currentResult");
|
|
_controller.sink.add(_currentResult!);
|
|
}
|
|
}
|
|
}
|