我如何在本机聊天应用程序中使用 GraphQl 订阅来从 GraphQl 查询中获取实时更新
How can i use GraphQl subscriptions in react-native chat application to get real-time updates from GraphQl queries
我在 react-native 聊天应用程序中使用 GraphQl APIs。我想在另一个用户向我发送消息而不刷新 API 时获得实时更新。我如何使用 GraphQl API 在 react-native 中使用 GraphQl 订阅或 Websocket 来做到这一点?
我应该使用不同的 URL 进行订阅和正常的 API 吗?
这是我的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;
我没有用 React Native 实现 Apollo,但我用我的 React 应用实现了它。根据我的经验,您应该为订阅 API 和普通 API 使用不同的 URL。然后,用import { split } from 'apollo-link'
拆分links,这样就可以给每个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 ...
}
我在 react-native 聊天应用程序中使用 GraphQl APIs。我想在另一个用户向我发送消息而不刷新 API 时获得实时更新。我如何使用 GraphQl API 在 react-native 中使用 GraphQl 订阅或 Websocket 来做到这一点?
我应该使用不同的 URL 进行订阅和正常的 API 吗?
这是我的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;
我没有用 React Native 实现 Apollo,但我用我的 React 应用实现了它。根据我的经验,您应该为订阅 API 和普通 API 使用不同的 URL。然后,用import { split } from 'apollo-link'
拆分links,这样就可以给每个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 ...
}