flutter getx web sockets - 流数据级联到提供者和控制器

raa*_*ne7 3 stream dart flutter flutter-getx

目标很简单

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

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

示例代码

实际调用者 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'),
    );
  }
Run Code Online (Sandbox Code Playgroud)

在提供者 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');
  }
Run Code Online (Sandbox Code Playgroud)

在控制器 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!');
          },
        );
  }
Run Code Online (Sandbox Code Playgroud)

homeview 调用 homecontroller

Dil*_*Nys 5

尝试使用映射来转换流:

 @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'),
  );
Run Code Online (Sandbox Code Playgroud)