【问题标题】:How can i use GraphQl subscriptions in react-native chat application to get real-time updates from GraphQl queries我如何在 react-native 聊天应用程序中使用 GraphQl 订阅从 GraphQl 查询中获取实时更新
【发布时间】: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;

【问题讨论】:

    标签: react-native websocket graphql messaging subscription


    【解决方案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 我已经更新了我的答案。希望对您有所帮助。
    猜你喜欢
    • 2019-12-09
    • 2017-09-01
    • 2018-02-01
    • 2017-11-30
    • 1970-01-01
    • 1970-01-01
    • 2019-04-12
    • 2021-08-18
    • 2020-08-19
    相关资源
    最近更新 更多