How can i use GraphQl subscriptions in react-native chat application to get real-time updates from GraphQl queries

让人想犯罪 __ 提交于 2020-06-27 16:30:47

问题


I am using GraphQl APIs in the react-native chat application. I want to get real-time updates when another user sends a message to me without refreshing the API. How can I do it using GraphQl API using GraphQl subscriptions or Websocket in react-native?

Should I use different URLs for subscription and normal API's?

Here is my 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:


I've not implemented Apollo with React Native but I did it with my React app. In my experience, you should use different URLs for subscription and normal APIs. Then, use import { split } from 'apollo-link' to split links, so you can send data to each link depending on what kind of operation is being sent. You can read more about subscription in Apollo here.
This is my client.js file. Hopefully, it can help you.

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,
})

This is my component where I integrate queries with subscriptions:

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 ...
}


来源:https://stackoverflow.com/questions/62186904/how-can-i-use-graphql-subscriptions-in-react-native-chat-application-to-get-real

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!