【问题标题】:How can I setup an Apollo client in React for both upload and subscriptions?如何在 React 中为上传和订阅设置 Apollo 客户端?
【发布时间】:2019-01-05 19:43:40
【问题描述】:

我想使用 React 设置一个 graphql 客户端,用于上传文件和处理来自 graphql 服务器的订阅。 文件上传和其他查询运行良好。问题在于订阅。我在浏览器控制台中收到以下错误: WebSocket connection to 'ws://localhost:3001/subscriptions' failed: Connection closed before receiving a handshake response

我使用apollo-upload-client 进行文件上传,使用apollo-link-ws 进行订阅。

我可以看到subscriptions-transport-ws 建议使用createNetworkInterfaceaddGraphQLSubscriptions,但这种方法与仅支持createUploadLinkapollo-upload-client 不兼容。

我被困住了。请帮忙。

我这样设置我的客户端:

import React from 'react';
import ApolloClient from 'apollo-client';
import { ApolloProvider } from 'react-apollo';
import { createUploadLink } from 'apollo-upload-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { ApolloLink, Observable, split } from 'apollo-link';
import { WebSocketLink } from 'apollo-link-ws';
import { getMainDefinition } from 'apollo-utilities';


const cache = new InMemoryCache();

const request = async (operation) => {
    const token = localStorage.getItem('token');
    operation.setContext({
        headers: {
            authorization: token ? `Bearer ${token}` : '',
        },
    });
};

const httpLink = createUploadLink({ uri: 'http://localhost:3001/graphql' });

// Create a WebSocket link:
const wsLink = new WebSocketLink({
    uri: 'ws://localhost:3001/subscriptions',
    options: {
        reconnect: true
    },
});

// 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 { kind, operation } = getMainDefinition(query);
        return kind === 'OperationDefinition' && operation === 'subscription';
    },
    wsLink,
    httpLink,
);


const requestLink = new ApolloLink((operation, forward) =>
    new Observable((observer) => {
        let handle;
        Promise.resolve(operation)
            .then(oper => request(oper))
            .then(() => {
                handle = forward(operation).subscribe({
                    next: observer.next.bind(observer),
                    error: observer.error.bind(observer),
                    complete: observer.complete.bind(observer),
                });
            })
            .catch(observer.error.bind(observer));

        return () => {
            if (handle) handle.unsubscribe();
        };
    }));

const apolloClient = new ApolloClient({
    link: ApolloLink.from([
        requestLink,
        link,
    ]),
    cache,
});

export const withApolloClient = App => (
    <ApolloProvider client={apolloClient}>
        <App client={apolloClient} />
    </ApolloProvider>
);

export default apolloClient;

【问题讨论】:

  • 您使用哪种服务器实现来支持 GraphQL 订阅?
  • 你的后端是nodejs还是其他的?
  • 服务器是用nodejs使用模块apollo-server-expressapollo-upload-serverexpressgraphqlsubscriptions-transport-ws制作的
  • 我试图思考问题所在。但它很难猜测和回答。你有机会分享源代码吗?我想尝试一下。我可能会得到一些更好的想法和解决方案。
  • 你弄明白了吗? @FedericoBellucci

标签: reactjs file-upload react-apollo apollo-client graphql-subscriptions


【解决方案1】:

我正在使用类似的配置,但不是从 apollo-link-ws 导入 WebSocketLink,而是从 @apollo/client 导入它。

通过该设置,我可以同时进行订阅和上传。

import { WebSocketLink } from "@apollo/client/link/ws";

【讨论】:

    【解决方案2】:

    我建议像this 一样使用graphql-server-express

    【讨论】:

      猜你喜欢
      • 2019-02-02
      • 2022-12-12
      • 2018-12-30
      • 2017-12-25
      • 2017-12-01
      • 2019-04-28
      • 2020-11-20
      • 2020-08-27
      • 2018-07-08
      相关资源
      最近更新 更多