我如何在 react-native 聊天应用程序中使用 GraphQl 订阅从 GraphQl 查询中获取实时更新
Posted
技术标签:
【中文标题】我如何在 react-native 聊天应用程序中使用 GraphQl 订阅从 GraphQl 查询中获取实时更新【英文标题】:How can i use GraphQl subscriptions in react-native chat application to get real-time updates from GraphQl queries 【发布时间】:2020-09-22 23:33:38 【问题描述】:我在 react-native 聊天应用程序中使用 GraphQl API。当另一个用户向我发送消息而不刷新 API 时,我想获得实时更新。如何在 react-native 中使用 GraphQl API 使用 GraphQl 订阅或 Websocket?
我应该为订阅和普通 API 使用不同的 URL 吗?
这是我的 config.js
import ApolloClient from 'apollo-client';
import createHttpLink from 'apollo-link-http';
import WebSocketLink from 'apollo-link-ws';
import HttpLink from 'apollo-boost';
import setContext from 'apollo-link-context';
import InMemoryCache from 'apollo-cache-inmemory';
import AsyncStorage from 'react-native';
// const httpLink = createHttpLink(
// uri: 'https://graphql.chat.dev.com/graphql',
// );
// const link = new HttpLink(
// uri: `https://graphql.chat.dev.com/graphql`,
// headers:
// Authorization: AsyncStorage.getItem('@user_token');
//
// );
const link = new WebSocketLink(
uri: `wss://graphql.chat.dev.com/graphql`,
options:
reconnect: true,
connectionParams:
headers:
Authorization: AsyncStorage.getItem('@user_token');
)
const defaultOptions =
query:
fetchPolicy: "network-only",
errorPolicy: "all"
;
const client = new ApolloClient(
link: link,
cache: new InMemoryCache(),
defaultOptions
);
export default client;
【问题讨论】:
【参考方案1】:我没有用 React Native 实现 Apollo,但我用我的 React 应用程序实现了。根据我的经验,您应该为订阅和普通 API 使用不同的 URL。然后,使用import split from 'apollo-link'
来拆分链接,这样就可以给每个链接发送数据了
取决于发送的操作类型。您可以在 Apollo here 中阅读有关订阅的更多信息。
这是我的client.js
文件。希望对您有所帮助。
import ApolloClient from 'apollo-client'
import createUploadLink from 'apollo-upload-client'
import InMemoryCache from 'apollo-cache-inmemory'
import setContext from 'apollo-link-context'
import split from 'apollo-link'
import WebSocketLink from 'apollo-link-ws'
import getMainDefinition from 'apollo-utilities'
const getToken = () => localStorage.getItem('AUTH_TOKEN')
const APOLLO_SERVER ="APOLLO_SERVER url"
const APOLLO_SOCKET ="APOLLO_SOCKET url"
// Create an http link:
const httpLink = createUploadLink(
uri: APOLLO_SERVER,
credentials: 'same-origin',
)
const authLink = setContext((_, headers ) =>
const token = getToken()
return
headers:
...headers,
authorization: token ? `Bearer $token` : '',
,
)
// Create a WebSocket link:
const wsLink = new WebSocketLink(
uri: APOLLO_SOCKET,
options:
reconnect: true,
connectionParams:
Authorization: getToken() ? `Bearer $getToken()` : '',
,
,
)
// using the ability to split links, you can send data to each link
// depending on what kind of operation is being sent
const link = split(
// split based on operation type
( query ) =>
const definition = getMainDefinition(query)
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
)
,
wsLink,
authLink.concat(httpLink)
)
const cache = new InMemoryCache()
const client = new ApolloClient(
cache,
link,
typeDefs,
resolvers,
)
这是我将查询与订阅集成的组件:
import React, useEffect from 'react'
import useQuery from '@apollo/react-hooks'
import gql from 'graphql-tag'
...
// query for querying message list
const GET_MESSAGE_LIST = gql`...`
// subscription for listening new message
const ON_MESSAGE_CREATED = gql`...`
const ChatView = props =>
const data, loading, subscribeToMore = useQuery(GET_MESSAGE_LIST,
notifyOnNetworkStatusChange: true,
variables:
query:
limit: 10,
userId: props.userId,
,
,
)
useEffect(() =>
subscribeToMore(
document: ON_MESSAGE_CREATED,
variables: filter: userId: props.userId ,
shouldResubscribe: true,
updateQuery: (prev, subscriptionData ) =>
let newMessage = subscriptionData.data.onZaloMessageCreated
return Object.assign(, prev,
messageList:
...prev.messageList,
items:
prev.messageList.items.filter(
item => item.id === newMessage.id
).length === 0
? [newMessage, ...prev.messageList.items]
: prev.messageList.items,
,
)
,
)
, [subscribeToMore])
return ...
【讨论】:
你能给我一个示例如何在聊天应用程序中将查询与订阅集成? @PratapPenmetsa 我已经更新了我的答案。希望对您有所帮助。以上是关于我如何在 react-native 聊天应用程序中使用 GraphQl 订阅从 GraphQl 查询中获取实时更新的主要内容,如果未能解决你的问题,请参考以下文章
react-native FlatList 滚动到底部的聊天应用程序
TextInput 在 react-native 中隐藏在键盘后面