У меня есть простой пример кода сервера gRP C приветствия, написанный на go и экспортированный как C библиотека, которую я пытаюсь запустить с помощью приложения flutter, используя go -flutter настольный движок через ffi и dart Isolates.
Я создал функцию StopGrpc()
, которая работает, если я вызываю ее для остановки сервера gRP C.
Но если я не делаю этого вручную сначала активируйте функцию StopGrpc()
перед выходом из приложения, я продолжаю получать следующее waiting for isolates _startGrpc to check in
, которое никогда не заканчивается, и мне нужно принудительно закрыть приложение.
An Observatory debugger and profiler on Flutter test device is available at: http://127.0.0.1:50300/
go-flutter: closing application
Attempt:11 waiting for isolate _startGrpc to check in
Attempt:12 waiting for isolate _startGrpc to check in
Вот полная копия файла lib/main.dart
для справки:
/// Example code from: https://codingwithjoe.com/dart-fundamentals-isolates/
/// Flutter example code from: https://gist.github.com/jebright/a7086adc305615aa3a655c6d8bd90264
import 'dart:async';
import 'package:flutter/material.dart';
import 'dart:isolate';
import 'dart:ffi';
// import 'package:ffi/ffi.dart';
// -- Normal gRPC server type definitions --
typedef startgrpc_func = void Function();
typedef StartGrpc = void Function();
typedef stopgrpc_func = void Function();
typedef StopGrpc = void Function();
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Isolate Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Isolates'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Isolate _isolate;
bool _running = false;
static int _counter = 0;
String notification = "";
ReceivePort _receivePort;
void _start() async {
_running = true;
_receivePort = ReceivePort();
_isolate = await Isolate.spawn(_startGrpc, _receivePort.sendPort);
_receivePort.listen(_handleMessage, onDone: () {
print("done!");
});
}
static void _checkTimer(SendPort sendPort) async {
Timer.periodic(new Duration(seconds: 1), (Timer t) {
_counter++;
String msg = 'notification ' + _counter.toString();
print('SEND: ' + msg);
sendPort.send(msg);
});
}
static void _startGrpc(SendPort sendPort) async {
// -- Normal gRPC server start code --
final greeter = DynamicLibrary.open('assets/greeter.so');
final void Function() startGrpc = greeter
.lookup<NativeFunction<Void Function()>>('StartGrpc')
.asFunction();
String msg = "Started gRPC server...";
sendPort.send(msg);
startGrpc();
}
static void _stopGrpc() async {
// -- Normal gRPC server stop code --
final greeter = DynamicLibrary.open('assets/greeter.so');
final void Function() stopGrpc = greeter
.lookup<NativeFunction<Void Function()>>('StopGrpc')
.asFunction();
// String msg = "Stoped gRPC server...";
// sendPort.send(msg);
stopGrpc();
}
void _handleMessage(dynamic data) {
print('RECEIVED: ' + data);
setState(() {
notification = data;
});
}
void _stop() {
if (_isolate != null) {
setState(() {
_running = false;
notification = '';
});
_stopGrpc();
_receivePort.close();
_isolate.kill(priority: Isolate.immediate);
_isolate = null;
}
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(
notification,
),
],
),
),
floatingActionButton: new FloatingActionButton(
onPressed: _running ? _stop : _start,
tooltip: _running ? 'Timer stop' : 'Timer start',
child: _running ? new Icon(Icons.stop) : new Icon(Icons.play_arrow),
),
);
}
}
Если я сначала вызываю StopGrpc()
, чтобы остановить сервер gRP C, а затем закрывать приложение, приложение завершает работу без каких-либо проблем.
Обычный выход выглядит как это в консоли отладки:
An Observatory debugger and profiler on Flutter test device is available at: http://127.0.0.1:50300/
Greet function was invoked with greeting:<first_name:"Satinder" last_name:"Grewal" >
flutter: done!
go-flutter: closing application
Lost connection to device.
hover: App 'flutter_isolates' exited.
hover: Closing the flutter attach sub process..
Итак, мне нужно знать, где разместить StopGrpc()
функцию для запуска при закрытии / выходе из приложения.
Кто-нибудь, пожалуйста, скажите мне, как я могу запускать функцию остановки сервера при выходе приложение?
Это код go -grp c, который я компилирую для этого go -flutter-приложения как C библиотеку: https://github.com/satindergrewal/flutter-practice/blob/master/go_dart_ffi_c_shared/greet/greet_server/server.go
И это код флаттера, который я использую для тестирования изоляторов флаттера: https://github.com/satindergrewal/flutter-practice/tree/master/flutter_isolates
Я уже просил помощи у go -flutter и они указали мне, чтобы я спросил в справочных каналах флаттера / флаттера.
Был бы очень признателен за помощь по этому поводу.
Спасибо, Сатиндер