2

目标很简单

  • Flutter 应用程序通过 websockets 调用 graphql api
  • 应用程序视图调用控制器,控制器调用提供者,提供者通过 websockets 或 HTTP api 套接字调用调用 AWS appsync api
  • 我们不时从后端通过 websockets 接收来自 appsync api 或 HTTP api 套接字调用的数据流
  • 流需要级联回提供者,然后到控制器(这是关键步骤)
  • 控制器(不是提供者)将更新 obs 或反应变量,使 UI 反映更改

问题:数据是通过调用者中的 websockets 接收的,但从未作为流传递回提供者或控制器以反映更改

示例代码

实际调用者 orderdata.dart

  @override
  Stream<dynamic> subscribe({
    String query,
    Map<String, dynamic> variables,
  }) async* {
    debugPrint('===->subscribe===');
    // it can be any stream here, http or file or image or media
    final Stream<GraphQLResponse<String>> operation = Amplify.API.subscribe(
      GraphQLRequest<String>(
        document: query,
        variables: variables,
      ),
      onEstablished: () {
        debugPrint(
          '===->subscribe onEstablished ===',
        );
      },
    );

    operation.listen(
      (event) async* {
        final jsonData = json.decode(event.data.toString());
        debugPrint('===->subscription data $jsonData');
        yield jsonData;
      },
      onError: (Object e) => debugPrint('Error in subscription stream: $e'),
    );
  }

在提供者 orderprovider.dart

  Stream<Order> orderSubscription(String placeId) async* {
    debugPrint('===->=== $placeId');
    subscriptionResponseStream = orderData.subscribe(
      query: subscribeToMenuOrder,
      variables: {"place_id": placeId},
    );

    subscriptionResponseStream.listen((event) async* {
      debugPrint(
        "===->=== yielded $event",
      );
      yield event;
    });
    debugPrint('===->=== finished');
  }

在控制器 homecontroller.dart

  Future<void> getSubscriptionData(String placeId) async {
    debugPrint('===HomeController->getSubscriptionData===');
    OrderProvider().orderSubscription(placeId).listen(
          (data) {
            //this block is executed when data event is receivedby listener
            debugPrint('Data: $data');
            Get.snackbar('orderSubscription', data.toString());
          },
          onError: (err) {
            //this block is executed when error event is received by listener
            debugPrint('Error: $err');
          },
          cancelOnError:
              false, //this decides if subscription is cancelled on error or not
          onDone: () {
            //this block is executed when done event is received by listener
            debugPrint('Done!');
          },
        );
  }

homeview 调用 homecontroller

4

1 回答 1

5

尝试使用map来转换 Streams:

 @override
  Stream<dynamic> subscribe({
    String query,
    Map<String, dynamic> variables,
  }) {
    debugPrint('===->subscribe===');
    // it can be any stream here, http or file or image or media
    final Stream<GraphQLResponse<String>> operation = Amplify.API.subscribe(
      GraphQLRequest<String>(
        document: query,
        variables: variables,
      ),
      onEstablished: () {
        debugPrint(
          '===->subscribe onEstablished ===',
        );
      },
    );
    
    return operation.map((event) {
      return json.decode(event.data);
    });
  }

  // elsewhere

  final subscription = subscribe(
    query: 'some query', 
    variables: {},
  );

  subscription.listen(
    (jsonData) {
      debugPrint('===->subscription data $jsonData');
    },
    onError: (Object e) => debugPrint('Error in subscription stream: $e'),
  );
于 2021-10-25T22:51:36.543 回答