如何使用 Flutter 消费 GraphQL 订阅?

Posted

技术标签:

【中文标题】如何使用 Flutter 消费 GraphQL 订阅?【英文标题】:How to consume GraphQL Subscription with Flutter? 【发布时间】:2019-03-01 03:38:11 【问题描述】:

我正在使用 GraphQL 创建订阅,我需要使用 Flutter 来使用该订阅,但我不知道该怎么做,我需要的是类似于将绑定到订阅的 UI 组件的东西并且会自动刷新。

如有任何反馈,我将不胜感激。

【问题讨论】:

你在用什么库?你已经尝试过了吗? 我没有使用过库,我创建了自己的库,创建了对 GraphQL 的 API 调用 【参考方案1】:

我的 GraphqlServer 运行一个名为 getLogs 的订阅,它以以下格式返回日志信息。


  "data": 
    "getLogs": 
      "timeStamp": "18:09:24",
      "logLevel": "DEBUG",
      "file": "logger.py",
      "function": "init",
      "line": "1",
      "message": "Hello from logger.py"
    
  

如果您像我一样只想直接使用GraphQL Client,那么下面的示例可能会有所帮助。

import 'package:graphql/client.dart';
import 'package:graphql/internal.dart';
import 'package:flutter/material.dart';
import 'dart:async';

class LogPuller extends StatefulWidget 
  static final WebSocketLink _webSocketLink = WebSocketLink(
    url: 'ws://localhost:8000/graphql/',
    config: SocketClientConfig(
      autoReconnect: true,
    ),
  );

  static final Link _link = _webSocketLink;

  @override
  _LogPullerState createState() => _LogPullerState();


class _LogPullerState extends State<LogPuller> 
  final GraphQLClient _client = GraphQLClient(
    link: LogPuller._link,
    cache: InMemoryCache(),
  );

  // the subscription query should be of the following format. Note how the 'GetMyLogs' is used as the operation name below.
  final String subscribeQuery = '''
    subscription GetMyLogs
      getLogs
        timeStamp
        logLevel
        file
        function
        line
        message
      
    
    ''';
  Operation operation;

  Stream<FetchResult> _logStream;

  @override
  void initState() 
    super.initState();
    // note operation name is important. If not provided the stream subscription fails after first pull.
    operation = Operation(document: subscribeQuery, operationName: 'GetMyLogs');
    _logStream = _client.subscribe(operation);
  

  @override
  Widget build(BuildContext context) 
    return StreamBuilder(
      stream: _logStream,
      builder: (context, snapshot) 
        if (snapshot.connectionState == ConnectionState.waiting) 
          return Center(
            child: Container(
              child: CircularProgressIndicator(
                strokeWidth: 1.0,
              ),
            ),
          );
        
        if (snapshot.hasData) 
          return Center(
            child: Text(
              snapshot.data.data['getLogs']
                  ['message'], // This will change according to you needs.
            ),
          );
        
        return Container();
      ,
    );
  


当我使用 StreamBuilder 构建小部件时,它将负责关闭流。如果您不是这种情况,stream.listen() 方法将返回一个StreamSubscription&lt;FetchResult&gt; 对象,您可以调用cancel() 方法,该方法可以在有状态小部件的dispose() 方法内完成,或者对于独立@ 的任何此类方法987654329@客户。

【讨论】:

【参考方案2】:

您可以查看下一个库https://github.com/zino-app/graphql-flutter

【讨论】:

我正在尝试使用那个库,但我不知道应该在哪里初始化socketClient,你能帮我吗?【参考方案3】:

只要找出这个库的bug,就可以通过ctrl+点击Subscription打开subscription.dart文件。在该文件中,很容易看到 socketClient 变量为空。因此,只需在 initState() 函数中定义它,如文档中所示。重新启动您的应用程序。它就像一个魅力。因此,基本上,您只需要在 subscription.dart 文件中初始化该变量即可。

【讨论】:

以上是关于如何使用 Flutter 消费 GraphQL 订阅?的主要内容,如果未能解决你的问题,请参考以下文章

如何使 Flutter graphql 订阅与轮渡包一起使用?

GraphQL:如何从计划的议程作业发布订阅

如何将使用graphQL的api响应转换为flutter中的Plain Old Dart Object?

如何配置graphql-flutter和apollo sever以使应用程序停止与websocket断开连接

如何在 graphql_flutter 中重试对 GraphQLError 的请求

Flutter / GraphQL - 以自定义类型为参数的突变