react-native - 我如何在react-native聊天应用程序中使用GraphQl订阅来从GraphQl查询中获取实时更新

标签 react-native websocket graphql messaging subscription

我在react-native聊天应用程序中使用GraphQl API。我希望在其他用户向我发送消息时获得实时更新,而无需刷新 API。如何使用 GraphQl API 使用 GraphQl 订阅或 React-native 中的 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 使用不同的 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 ...
}

关于react-native - 我如何在react-native聊天应用程序中使用GraphQl订阅来从GraphQl查询中获取实时更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62186904/

相关文章:

javascript - React Native - iOS - 本地镜像不可见(适用于 android)

javascript - Websockets 客户端 API 中的 HTTP header

scala - 如何了解 Sangria GraphQL 中对象解析器中请求的字段

android - 带有 React Navigation 5 的 Expo React Native 应用程序在从 Navigator 触摸初始屏幕时在 Android 上崩溃

android - 如何在react-native android应用程序中单击时将铃声模式更改为静音/响铃/振动?

android - 无法在 android socketio 客户端与 socketio 服务器之间建立连接

graphql - 优化 graphql 数据库查询

node.js - FetchError : graphql failed,原因:无法验证第一个证书

django - 如何通过 native react 中的 header 将 JWT token 传递给 django Rest api?

java - Tomcat 上的 Websockets : how to shutdown the server cleanly?