gpt4 book ai didi

networking - 没有互联网时 Flutter 中的 gRPC 崩溃

转载 作者:IT老高 更新时间:2023-10-28 12:44:03 27 4
gpt4 key购买 nike

我正在使用 gRPC 开发 Flutter 应用程序,一切正常,直到我决定看看如果没有互联网连接会发生什么。

执行此操作并发出请求后,我收到以下错误:

E/flutter (26480): 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.)

问题是即使重新启用连接后,错误仍然存​​在。
我必须重新创建 clientChannel 吗?

const String serverUrl = 'theaddress.com';
const int serverPort = 50051;

final ClientChannel defaultClientChannel = ClientChannel(
serverUrl,
port: serverPort,
options: const ChannelOptions(
credentials: const ChannelCredentials.insecure(),
),
);

我只想抛出一些错误,但一旦互联网连接恢复正常工作。

最佳答案

根据@Ishaan 的建议,我使用 Connectivity 包创建了一个客户端,该客户端在 Internet 备份时重新连接。到目前为止,它似乎正在工作。

import 'dart:async';

import 'package:connectivity/connectivity.dart';
import 'package:flutter_worker_app/generated/api.pbgrpc.dart';
import 'package:grpc/grpc.dart';
import 'package:rxdart/rxdart.dart';

class ConnectiveClient extends ApiClient {

final CallOptions _options;
final Connectivity _connectivity;
ClientChannel _channel;
bool hasRecentlyFailed = false;


ConnectiveClient(this._connectivity, this._channel, {CallOptions options})
: _options = options ?? CallOptions(),
super(_channel) {
//TODO: Cancel connectivity subscription
_connectivity.onConnectivityChanged.listen((result) {
if (hasRecentlyFailed && result != ConnectivityResult.none) {
_restoreChannel();
}
});
}

///Create new channel from original channel
_restoreChannel() {
_channel = ClientChannel(_channel.host,
port: _channel.port, options: _channel.options);
hasRecentlyFailed = false;
}

@override
ClientCall<Q, R> $createCall<Q, R>(
ClientMethod<Q, R> method, Stream<Q> requests,
{CallOptions options}) {
//create call
BroadcastCall<Q, R> call = createChannelCall(
method,
requests,
_options.mergedWith(options),
);
//listen if there was an error
call.response.listen((_) {}, onError: (Object error) async {
//Cannot connect - we assume it's internet problem
if (error is GrpcError && error.code == StatusCode.unavailable) {
//check connection
_connectivity.checkConnectivity().then((result) {
if (result != ConnectivityResult.none) {
_restoreChannel();
}
});
hasRecentlyFailed = true;
}
});
//return original call
return call;
}

/// Initiates a new RPC on this connection.
/// This is copy of [ClientChannel.createCall]
/// The only difference is that it creates [BroadcastCall] instead of [ClientCall]
ClientCall<Q, R> createChannelCall<Q, R>(
ClientMethod<Q, R> method, Stream<Q> requests, CallOptions options) {
final call = new BroadcastCall(method, requests, options);
_channel.getConnection().then((connection) {
if (call.isCancelled) return;
connection.dispatchCall(call);
}, onError: call.onConnectionError);
return call;
}
}

///A ClientCall that can be listened multiple times
class BroadcastCall<Q, R> extends ClientCall<Q, R> {
///I wanted to use super.response.asBroadcastStream(), but it didn't work.
///I don't know why...
BehaviorSubject<R> subject = BehaviorSubject<R>();

BroadcastCall(
ClientMethod<Q, R> method, Stream<Q> requests, CallOptions options)
: super(method, requests, options) {
super.response.listen(
(data) => subject.add(data),
onError: (error) => subject.addError(error),
onDone: () => subject.close(),
);
}

@override
Stream<R> get response => subject.stream;
}

关于networking - 没有互联网时 Flutter 中的 gRPC 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54105481/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com