Flutter WebSocket GraphQL通信插件gql_websocket_link的使用
Flutter WebSocket GraphQL通信插件gql_websocket_link的使用
介绍
gql_websocket_link
是一个用于在 Flutter 应用中通过 WebSocket 与 GraphQL 后端进行通信的插件。它支持订阅(subscriptions)、查询(queries)和变更(mutations)。该插件支持两种 WebSocket 子协议:graphql-ws
和 graphql-transport-ws
,分别通过 WebSocketLink
和 TransportWebSocketLink
类实现。
主要特性
- 自动重连:支持
autoReconnect
,在连接断开后会自动重新订阅。 - 协议支持:支持
graphql-ws
和graphql-transport-ws
协议。 - 灵活配置:可以根据需要选择不同的 WebSocket 实现方式。
使用方法
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 gql_websocket_link
和 gql_link
依赖:
dependencies:
gql_websocket_link: ^0.4.0
gql_link: ^0.4.0
然后运行 flutter pub get
来安装依赖。
2. 使用 WebSocketLink
/ graphql-ws
协议
import 'package:gql_link/gql_link.dart';
import 'package:gql_websocket_link/gql_websocket_link.dart';
void main() {
// 创建 WebSocketLink 实例,指定 GraphQL 服务器的 WebSocket 端点
final link = Link.from([
WebSocketLink("ws://<GRAPHQL_SERVER_ENDPOINT>/graphql"),
]);
// 使用 link 进行 GraphQL 操作
// 例如,执行查询、变更或订阅
}
3. 使用 TransportWebSocketLink
/ graphql-transport-ws
协议
import 'package:gql_link/gql_link.dart';
import 'package:gql_websocket_link/gql_websocket_link.dart';
void main() {
// 创建 TransportWebSocketLink 实例,指定 WebSocketMaker
final link = Link.from([
TransportWebSocketLink(
TransportWsClientOptions(
socketMaker: WebSocketMaker.url(() => "ws://<GRAPHQL_SERVER_ENDPOINT>/graphql"),
),
),
]);
// 使用 link 进行 GraphQL 操作
// 例如,执行查询、变更或订阅
}
完整示例 Demo
以下是一个完整的示例,展示了如何使用 gql_websocket_link
进行 WebSocket GraphQL 订阅、查询和变更操作。假设我们有一个 GraphQL 服务器运行在 ws://localhost:5000/graphql
,并且我们想要订阅某个事件、查询数据并执行变更。
import 'package:flutter/material.dart';
import 'package:gql_link/gql_link.dart';
import 'package:gql_websocket_link/gql_websocket_link.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await initHiveForFlutter();
final HttpLink httpLink = HttpLink('http://localhost:5000/graphql');
final WebSocketLink webSocketLink = WebSocketLink(
'ws://localhost:5000/graphql',
config: SocketClientConfig(
autoReconnect: true,
inactivityTimeout: const Duration(seconds: 30),
),
);
final Link link = Link.split(
(request) => request.isSubscription,
webSocketLink,
httpLink,
);
runApp(
GraphQLProvider(
client: ValueNotifier<GraphQLClient>(
GraphQLClient(
link: link,
cache: GraphQLCache(store: HiveStore()),
),
),
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter GraphQL WebSocket Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
[@override](/user/override)
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter GraphQL WebSocket Demo'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Query(
options: QueryOptions(
document: gql(r'''
query GetItems {
items {
id
name
}
}
'''),
),
builder: (QueryResult result, {VoidCallback? refetch, FetchMore? fetchMore}) {
if (result.hasException) {
return Text(result.exception.toString());
}
if (result.isLoading) {
return Center(child: CircularProgressIndicator());
}
final items = result.data?['items'] as List<dynamic>?;
return ListView.builder(
shrinkWrap: true,
itemCount: items?.length ?? 0,
itemBuilder: (context, index) {
final item = items?[index];
return ListTile(
title: Text(item?['name']),
);
},
);
},
),
Subscription(
options: SubscriptionOptions(
document: gql(r'''
subscription OnNewItemAdded {
newItemAdded {
id
name
}
}
'''),
),
builder: (QueryResult result, {VoidCallback? refetch, FetchMore? fetchMore}) {
if (result.hasException) {
return Text(result.exception.toString());
}
if (result.isLoading) {
return Center(child: CircularProgressIndicator());
}
final newItem = result.data?['newItemAdded'];
if (newItem != null) {
return ListTile(
title: Text('New Item Added: ${newItem['name']}'),
);
}
return Container();
},
),
ElevatedButton(
onPressed: () {
final MutationOptions options = MutationOptions(
document: gql(r'''
mutation AddItem($name: String!) {
addItem(name: $name) {
id
name
}
}
'''),
variables: {'name': 'New Item'},
);
final GraphQLClient client = GraphQLProvider.of(context).value;
client.mutate(options).then((result) {
if (result.hasException) {
print(result.exception.toString());
} else {
print('Item added: ${result.data?['addItem']['name']}');
}
});
},
child: Text('Add New Item'),
),
],
),
),
);
}
}
更多关于Flutter WebSocket GraphQL通信插件gql_websocket_link的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter WebSocket GraphQL通信插件gql_websocket_link的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter项目中使用gql_websocket_link
插件来实现WebSocket GraphQL通信的示例代码。这个示例将展示如何配置GraphQL客户端以使用WebSocket进行订阅操作。
首先,确保你已经在pubspec.yaml
文件中添加了必要的依赖项:
dependencies:
flutter:
sdk: flutter
graphql_flutter: ^5.0.0 # 或者最新版本
gql: ^0.13.0 # 或者最新版本
gql_exec: ^0.3.0 # 或者最新版本
gql_websocket_link: ^0.3.0 # 或者最新版本
然后,运行flutter pub get
来安装这些依赖项。
接下来,在你的Flutter项目中,按照以下步骤配置和使用gql_websocket_link
:
- 定义GraphQL订阅查询:
import 'package:gql/ast.dart';
const String subscriptionQuery = r'''
subscription OnMessageUpdate {
messageUpdated {
id
content
}
}
''';
final DocumentNode subscriptionDocument = parseString(subscriptionQuery);
- 创建WebSocket链接:
import 'package:gql/link.dart';
import 'package:gql_websocket_link/gql_websocket_link.dart';
// 替换为你的GraphQL服务器WebSocket端点
final String websocketUrl = 'wss://your-graphql-endpoint/subscriptions';
// 创建WebSocket链接
final WebSocketLink webSocketLink = WebSocketLink(
url: websocketUrl,
config: WebSocketLinkConfig(
// 如果需要认证头,可以在这里添加
headers: () async => {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
},
),
);
- 创建GraphQL客户端:
import 'package:graphql_flutter/graphql_flutter.dart';
// 使用WebSocket链接创建ValueNotifierLink(可选,用于缓存)
final ValueNotifier<GraphQLClient> client = ValueNotifier(
GraphQLClient(
link: webSocketLink,
cache: GraphQLCache(),
),
);
- 在Flutter组件中使用订阅:
import 'package:flutter/material.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
class SubscriptionScreen extends StatefulWidget {
@override
_SubscriptionScreenState createState() => _SubscriptionScreenState();
}
class _SubscriptionScreenState extends State<SubscriptionScreen> {
final StreamController<Map<String, dynamic>> _controller = StreamController();
@override
void dispose() {
_controller.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('GraphQL WebSocket Subscription')),
body: StreamBuilder<Object?>(
stream: _controller.stream,
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
}
if (snapshot.hasData) {
final data = snapshot.data as Map<String, dynamic>;
return ListView.builder(
itemCount: data['messageUpdated']?.length ?? 0,
itemBuilder: (context, index) {
final message = data['messageUpdated']![index];
return ListTile(
title: Text('ID: ${message['id']}, Content: ${message['content']}'),
);
},
);
}
return Center(child: CircularProgressIndicator());
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// 发起订阅
client.value.subscribe(
subscriptionDocument,
rootValue: () => _controller.sink,
);
},
tooltip: 'Start Subscription',
child: Icon(Icons.play_arrow),
),
);
}
}
注意:上面的示例代码中的rootValue
部分需要根据你的实际需求进行调整,因为gql_websocket_link
的API可能会要求你提供一个处理订阅响应的方式。在这个例子中,我们直接将数据发送到_controller.sink
,但你可能需要根据你的业务逻辑进行调整。
另外,上面的代码假设你已经有一个正在运行的GraphQL服务器,并且该服务器支持WebSocket订阅。如果服务器需要认证,请确保在WebSocketLinkConfig
的headers
中提供了正确的认证信息。
请根据你的具体需求和环境调整上述代码。希望这个示例能帮助你理解如何在Flutter项目中使用gql_websocket_link
插件进行WebSocket GraphQL通信。