Add status command receiver

This commit is contained in:
problematicconsumer
2023-08-28 13:15:57 +03:30
parent 4f5c6c12a5
commit 01980ba28d
9 changed files with 147 additions and 6 deletions

View File

@@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:ffi';
import 'dart:io';
import 'dart:isolate';
import 'package:combine/combine.dart';
import 'package:ffi/ffi.dart';
@@ -16,6 +17,8 @@ final _logger = Loggy('FFISingboxService');
class FFISingboxService with InfraLogger implements SingboxService {
static final SingboxNativeLibrary _box = _gen();
Stream<String>? _statusStream;
static SingboxNativeLibrary _gen() {
String fullPath = "";
if (Platform.environment.containsKey('FLUTTER_TEST')) {
@@ -47,6 +50,7 @@ class FFISingboxService with InfraLogger implements SingboxService {
workingDir.toNativeUtf8().cast(),
tempDir.toNativeUtf8().cast(),
);
_box.setupOnce(NativeApi.initializeApiDLData);
return right(unit);
},
),
@@ -119,6 +123,46 @@ class FFISingboxService with InfraLogger implements SingboxService {
);
}
@override
Stream<String> watchStatus() {
if (_statusStream != null) return _statusStream!;
final receiver = ReceivePort('status receiver');
final statusStream = receiver.asBroadcastStream(
onCancel: (_) {
_logger.debug("stopping status command client");
final err = _box.stopCommandClient(1).cast<Utf8>().toDartString();
if (err.isNotEmpty) {
_logger.warning("error stopping status client");
}
receiver.close();
_statusStream = null;
},
).map(
(event) {
if (event case String _) {
if (event.startsWith('error:')) {
loggy.warning("[status client] error received: $event");
throw event.replaceFirst('error:', "");
}
return event;
}
loggy.warning("[status client] unexpected type, msg: $event");
throw "invalid type";
},
);
final err = _box
.startCommandClient(1, receiver.sendPort.nativePort)
.cast<Utf8>()
.toDartString();
if (err.isNotEmpty) {
loggy.warning("error starting status command: $err");
throw err;
}
return _statusStream = statusStream;
}
@override
Stream<String> watchLogs(String path) {
var linesRead = 0;

View File

@@ -67,6 +67,12 @@ class MobileSingboxService with InfraLogger implements SingboxService {
);
}
@override
Stream<String> watchStatus() {
// TODO: implement watchStatus
return const Stream.empty();
}
@override
Stream<String> watchLogs(String path) {
return _logsChannel.receiveBroadcastStream().map(

View File

@@ -26,5 +26,7 @@ abstract interface class SingboxService {
TaskEither<String, Unit> stop();
Stream<String> watchStatus();
Stream<String> watchLogs(String path);
}