这是我的
graphqlClient.ts
文件:
import {
ApolloClient,
HttpLink,
ApolloLink,
InMemoryCache,
concat,
Operation,
NextLink,
FetchResult,
Observable,
split,
} from '@apollo/client';
import { getMainDefinition } from '@apollo/client/utilities';
import auth, { FirebaseAuthTypes } from '@react-native-firebase/auth';
import Config from 'react-native-config';
const httpLink = new HttpLink({ uri: Config.BE_BASE_URL });
import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
import { createClient } from 'graphql-ws';
const wsLink = new GraphQLWsLink(
createClient({
url: 'ws://my-gqlserver.railway.app/graphql',
}),
);
const splitLink = split(
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
);
},
wsLink,
httpLink,
);
const authMiddleware = new ApolloLink(
(operation: Operation, forward: NextLink): Observable<FetchResult> => {
return new Observable(observer => {
(async () => {
const currentUser: FirebaseAuthTypes.User | null = auth().currentUser;
const token = currentUser ? await currentUser.getIdToken(false) : null;
operation.setContext({
headers: {
Authorization: token ? `Bearer ${token}` : '',
},
});
return forward(operation).subscribe({
next: observer.next.bind(observer),
error: observer.error.bind(observer),
complete: observer.complete.bind(observer),
});
})();
});
},
);
const graphQLClient = new ApolloClient({
cache: new InMemoryCache(),
link: concat(authMiddleware, splitLink),
});
export default graphQLClient;
这是查询:
export const SUBSCRIBE_TO_LOCATIONS = gql`
subscription Subscription {
locations
}
`;
在主屏幕上,我使用
useSubscription
中的 @apollo/client
钩子
HomeScreen.tsx
:
import { useSubscription, useQuery } from '@apollo/client';
import { SUBSCRIBE_TO_LOCATIONS } from '../graphql/queries';
const { data: subscriptionData, loading: subscritionLoading } =
useSubscription(SUBSCRIBE_TO_LOCATIONS, {
onData: subData => {
console.log('onData', subData);
},
});
console.log(subscriptionData, 'subscriptionData');
// iOS ==> undefined subscriptionData
// android ==> array of coordinates
我正在按照官方文档进行所有操作,对于 websocekt 协议,我正在使用
graphql-ws
,因为 subscriptions-transport-ws
已被弃用,如文档中所述。
我很确定一切都连接良好,因为在 Android 上它应该如何工作,所以我猜测我需要在 ios 上配置其他一些东西,但我不确定是什么。
抱歉来晚了,但我最近遇到了类似的问题;
改变这个
createClient({
url: 'ws://my-gqlserver.railway.app/graphql',
}),
);
到此
const wsLink = new GraphQLWsLink(
createClient({
url: 'wss://my-gqlserver.railway.app/graphql',
}),
);
基本上我们正在将不安全的
ws://
更改为安全的wss://
。 iOS 不允许从 http 或 ws 上的不安全链接加载。您可以通过编辑 info.plist 的传输安全设置来覆盖此行为,但我认为您处于 Expo 的托管工作流程中,除非您弹出,否则可能很难做到这一点。
干杯。