Flutter连接AWS AppSync订阅时出现DuplicatedOperationError问题
Flutter连接AWS AppSync订阅触发DuplicatedOperationError且无法接收事件
我通过Flutter前端使用graphql_flutter库连接AWS AppSync GraphQL API,查询(Queries)和突变(Mutations)功能均正常,也能成功建立订阅所需的WebSocket连接。但当graphql_flutter发送如下start消息尝试订阅时:
{ "type": "start", "id": "061bf284-c738-4a83-96e9-c8cf4b17369e", "payload": { "data": "{\"query\":\"subscription TransportChanged {\n transportChange {\n id\n __typename\n }\n __typename\n}\"\,\"variables\":{}}", "extensions": { "authorization": { "Authorization": "base64encodedAuthorizationHeader", "host": "actual_api.appsync-api.eu-central-1.amazonaws.com" } } } }
会收到错误响应:
{ "id": "061bf284-c738-4a83-96e9-c8cf4b17369e", "type": "error", "payload": { "errors": [ { "errorType": "DuplicatedOperationError", "message": "Duplicated operation with id 061bf284-c738-4a83-96e9-c8cf4b17369e" } ] } }
随后会收到start_ack响应,但无法通过该连接接收任何订阅事件:
{ "id": "061bf284-c738-4a83-96e9-c8cf4b17369e", "type": "start_ack" }
我已经通过AWS AppSync QueryConsole测试过订阅功能,确认服务端正常,问题应该出在本地配置。
GraphQL客户端配置代码
var authSession = context.read<AppUser>().getAuthSessionFromState(); final String? authenticationToken = context.watch<AppUser>().authenticationToken; Link link; final HttpLink httpLink = HttpLink( graphqlUrl, ); if (authenticationToken != null && authenticationToken.isNotEmpty) { final AuthLink authLink = AuthLink( getToken: () async => authenticationToken, headerKey: 'Authorization'); graphQLClientIsAuthenticated = true; currentToken = authenticationToken; _tokenExpiry = authSession?.userPoolTokens?.idToken.claims.expiration; String toBase64(Map data) => base64.encode(utf8.encode(jsonEncode(data))); final authHeader = { "Authorization": authenticationToken, "host": graphqlHost, }; final encodedHeader = toBase64(authHeader); final WebSocketLink wsLink = WebSocketLink( "$graphqlRealTimeUrl?header=$encodedHeader&payload=e30=", config: SocketClientConfig( serializer: AppSyncRequest( authHeader: authHeader), inactivityTimeout: const Duration(seconds: 60), ), ); link = Link.split((request) => request.isSubscription, authLink.concat(wsLink), authLink.concat(httpLink)); } else { link = httpLink; }
AppSyncRequest序列化器实现
import 'dart:convert'; import 'package:gql/language.dart' show printNode; import 'package:graphql_flutter/graphql_flutter.dart'; class AppSyncRequest extends RequestSerializer { final Map<String, dynamic> authHeader; const AppSyncRequest({ required this.authHeader, }); @override Map<String, dynamic> serializeRequest(Request request) => { "data": jsonEncode({ "query": printNode(request.operation.document), "variables": request.variables.isEmpty?null: request.variables, }), "extensions": { "authorization": this.authHeader, } }; }
我已经排查过网络问题,排除了这类原因,求帮忙定位问题。
内容的提问来源于stack exchange,提问作者Chris Tim
相关产品推荐
相关产品推荐

