Я не использовал gRPC до сегодняшнего дня.
Так как я потратил время, чтобы попытаться смоделировать эту ошибку, я опубликую здесь свой ответ, но все мои сведения были получены под @ ishann ответом, за который я проголосовал и который должен быть принят один.
Я только что попробовал пример с миром дротиков .
У меня server
работает на моей машине и client
как приложение Flutter.
Когда я не запускаю сервер, я получаю сообщение об ошибке
gRPC Error (14, Error connecting: SocketException:
Но как только сервер работает, все начинают работать, как и ожидалось, но потом я понял, что каждый раз воссоздаю канал, так что это не сценарий OP.
Это мой первый код флаттера:
void _foo() async {
final channel = new ClientChannel('192.168.xxx.xxx',
port: 50051,
options: const ChannelOptions(
credentials: const ChannelCredentials.insecure()));
final stub = new GreeterClient(channel);
final name = 'world';
var _waitHelloMessage = true;
while (_waitHelloMessage) {
try {
final response = await stub.sayHello(new HelloRequest()..name = name);
print('Greeter client received: ${response.message}');
_waitHelloMessage = false;
} catch (e) {
print('Caught error: $e');
sleep(Duration(seconds: 1));
}
}
print('exiting');
await channel.shutdown();
}
То же самое происходит, если я перевожу устройство в режим airplain и затем переключаюсь обратно в нормальное соединение Wi-Fi / lte.
В этом другом игровом проекте я воспроизвел либо
Caught error: gRPC Error (14, Error making call: Bad state: The http/2 connection is no longer active and can therefore not be used to make new streams.)
Из которого вы не можете выйти без воссоздания канала, и
Caught error: gRPC Error (14, Error connecting: SocketException: OS Error: Connection refused, errno = 111, address = 192.168.1.58, port = 38120)
(например, выключить сервер), с которого вы можете снова встать без воссоздания канала.
Прежний код ошибки не так легко получить, потому что кажется, что канал дросселя между Wi-Fi и lte соединением.
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app_test_grpc/grpc/generated/helloworld.pbgrpc.dart';
import 'package:grpc/grpc.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
ClientChannel _channel;
@override
void dispose() {
_shutdown();
super.dispose();
}
void _shutdown() async {
if (null != _channel) {
print('shutting down...');
await _channel.shutdown();
print('shut down');
_channel = null;
} else {
print ('connect first');
}
}
void _connect() {
print('connecting...');
_channel = new ClientChannel('192.168.xxx.xxx',
port: 50051,
options: const ChannelOptions(
credentials: const ChannelCredentials.insecure()));
print('connected');
}
void _sayHello() async {
if (_channel != null) {
final stub = new GreeterClient(_channel);
final name = 'world';
try {
final response = await stub.sayHello(new HelloRequest()..name = name);
print('Greeter client received: ${response.message}');
} catch (e) {
print('Caught error: $e');
//sleep(Duration(seconds: 2));
}
//print('exiting');
//await channel.shutdown();
} else {
print('connect first!');
}
}
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: Padding(
padding: const EdgeInsets.only(left: 36.0),
child: Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: FloatingActionButton(
onPressed: _connect,
tooltip: 'Increment',
child: Icon(Icons.wifi),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: FloatingActionButton(
onPressed: _sayHello,
tooltip: 'Increment',
child: Icon(Icons.send),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: FloatingActionButton(
onPressed: _shutdown,
tooltip: 'Increment',
child: Icon(Icons.close),
),
),
],
),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
Это мое flutter doctor -v
, если бы можно было помочь:
$ flutter doctor -v
[✓] Flutter (Channel beta, v1.0.0, on Mac OS X 10.14.1 18B75, locale en-IT)
• Flutter version 1.0.0 at /Users/shadowsheep/flutter/flutter
• Framework revision 5391447fae (6 weeks ago), 2018-11-29 19:41:26 -0800
• Engine revision 7375a0f414
• Dart version 2.1.0 (build 2.1.0-dev.9.4 f9ebf21297)
[✓] Android toolchain - develop for Android devices (Android SDK 28.0.3)
• Android SDK at /Users/shadowsheep/Library/Android/sdk
• Android NDK location not configured (optional; useful for native profiling support)
• Platform android-28, build-tools 28.0.3
• Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1248-b01)
• All Android licenses accepted.
[✓] iOS toolchain - develop for iOS devices (Xcode 10.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 10.1, Build version 10B61
• ios-deploy 1.9.4
• CocoaPods version 1.5.3
[✓] Android Studio (version 3.3)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin version 31.3.3
• Dart plugin version 182.5124
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1248-b01)
[✓] VS Code (version 1.30.1)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 2.21.1
[✓] Connected device (1 available)
[...]
• No issues found!