2024年React中用ApolloClient对接AWS AppSync订阅遇阻求助
解决React中ApolloClient对接AWS AppSync订阅的"Subscriptions over MQTT is not supported"错误
问题分析
你遇到的Subscriptions over MQTT is not supported错误,通常是WebSocket连接建立失败触发MQTT fallback导致的,核心原因包括:
- 未正确初始化
httpLink导致链接配置无效 - 异步获取JWT Token的时机错误,认证信息未正确传递
- 可能缺少AWS AppSync底层依赖支持
解决方案
1. 修复链接配置与异步Token处理
修正ApolloClient的配置,确保httpLink正确定义,同时异步获取Token的逻辑适配AppSync的认证要求:
import { ApolloLink, ApolloProvider, createHttpLink } from "@apollo/client"; import { InMemoryCache } from "@apollo/client/cache"; import { ApolloClient } from "@apollo/client/core"; import { createSubscriptionHandshakeLink } from "aws-appsync-subscription-link"; // 1. 正确创建HTTP链接 const httpLink = createHttpLink({ uri: process.env.REACT_APP_GRAPHQL_URL, }); // 2. 创建订阅链接,用异步函数传递认证信息 const subscriptionLink = createSubscriptionHandshakeLink( { url: process.env.REACT_APP_GRAPHQL_URL, region: "eu-east-1", // 用async函数确保Token获取完成后再返回认证信息 auth: async () => ({ type: "OPENID_CONNECT", jwtToken: await getToken(), // 直接使用你的异步Token获取方法 }), }, httpLink ); // 3. 拆分链接:订阅用subscriptionLink,查询/突变用HTTP+认证链接 const authLink = new ApolloLink((operation, forward) => { return getToken().then((jwtToken) => { operation.setContext({ headers: { Authorization: jwtToken, }, }); return forward(operation); }); }); const link = ApolloLink.split( // 判断是否为订阅操作 (operation) => operation.query.definitions.some( (def) => def.kind === "OperationDefinition" && def.operation === "subscription" ), subscriptionLink, authLink.concat(httpLink) ); // 初始化ApolloClient export const client = new ApolloClient({ link, cache: new InMemoryCache({/* 你的缓存配置 */}) }); export const Apollo = ({children}) => ( <ApolloProvider client={client}>{children}</ApolloProvider> );
2. 修复订阅代码的变量重复定义问题
你的测试代码中存在重复定义subscriptionData的错误,修正如下:
const SUBS_QUERY= gql` subscription onExampleMutation( $event: exampleMutationRequest! ) { onExampleMutation(event: $event) { message status statusCode } } `; const {data: subscriptionData, loading: subscriptionLoader} = useSubscription( SUBS_QUERY, {variables: {event: {...DEFAULT}}}, ); // 避免重复定义变量,同时处理data为null的情况 const formattedSubscriptionData = subscriptionLoader ? [] : subscriptionData || []; console.log("Output from subscription: ", formattedSubscriptionData);
3. 安装必要依赖
虽然aws-appsync-subscription-link文档未明确说明,但底层依赖aws-appsync是WebSocket连接的必要支撑,执行安装:
npm install aws-appsync aws-appsync-subscription-link
4. 验证AppSync配置
- 确认你的AppSync API已启用WebSocket协议(在AppSync控制台的API设置中查看)
- 确保你的JWT Token包含订阅操作的权限(检查IAM或OIDC的权限策略)
- 确认
process.env.REACT_APP_GRAPHQL_URL指向正确的AppSync API端点(格式应为https://xxx.appsync-api.eu-east-1.amazonaws.com/graphql)
内容的提问来源于stack exchange,提问作者Akshit Aggarwal
相关产品推荐
相关产品推荐

