通过 apollo 连接到 graphql-yoga 服务器进行订阅的正确方法是啥?

Posted

技术标签:

【中文标题】通过 apollo 连接到 graphql-yoga 服务器进行订阅的正确方法是啥?【英文标题】:What is the correct way to connect to a graphql-yoga server via apollo for subscriptions?通过 apollo 连接到 graphql-yoga 服务器进行订阅的正确方法是什么? 【发布时间】:2019-11-30 08:23:55 【问题描述】:

阿波罗客户端:2.6.3 阿波罗链接-http:1.5.15 apollo-link-ws:1.0.18 订阅-传输-ws:0.9.16

所以我有一个前端(节点)服务器,它连接到后端(graphql-yoga)服务器,如下所示:

  const httpLink = createHttpLink(
    uri: 'https://localhost:4444',
    credentials: 'include',
  );

  const wsLink = process.browser ? new WebSocketLink(
    uri: 'wss://eu1.prisma.sh/MyID/MyProject/dev',
    options: 
      reconnect: true,
      timeout: 3000,
    
  ) : null;

  const authLink = setContext(() => 
    return 
      headers: 
        ...headers,
      
    
  );

  const link = process.browser ? split(
  ( query ) => 
    const definition = getMainDefinition(query);
    return (
      definition.kind === 'OperationDefinition' &&
      definition.operation === 'subscription'
    );
  ,
  wsLink,
  httpLink,
  ) : httpLink;

  const client = new ApolloClient(
    link: authLink.concat(link),
    ...
  );

查询和变异解析器被正确触发,但订阅解析器没有被触发。我假设那是因为我没有直接连接到 graphql-yoga。 但是如果我将 WebSocketLink uri 更改为 ws://localhost:4000 这会导致:

failed: Error during WebSocket handshake: Unexpected response code: 200

要发出的错误信息。

graphql-yoga 服务器本身与 prisma 建立订阅连接,如下所示:

const options = 
  subscriptions: 'https://eu1.prisma.sh/MyID/MyProject/dev',
;

// start it!!
server.start(options, ( port ) =>
    console.log(`Server is now running on port http://localhost:$port`),
);

而我的订阅解析器如下:

  const Subscription = 
      order: 
        async subscribe(parent, args, ctx, info) 
            return ctx.db.subscription.order(
              
                where: 
                    mutation_in: ['CREATED', 'UPDATED'],
                ,
              ,
              info
            ).catch(handleSubmitError);
        ,
      
  ;

如果我在 Playground 中运行以下订阅:

subscription 
  order 
    mutation
    node 
      id
      total
      createdAt
      items 
        id
        title
        price
        description
        mainDescription
        quantity
        image
      
    
  

并通过我的网站触发订单突变,正确 显示数据结果集:

但是订阅解析器没有被订阅调用操作:

const USER_ORDERS_SUBSCRIPTION = gql`
  subscription 
    order 
      mutation
      node 
        id
        total
        createdAt
        items 
          id
          title
          price
          description
          mainDescription
          quantity
          image
        
      
    
  
`;

        <Query query=USER_ORDERS_QUERY>
          ( subscribeToMore, data:  orders , loading, error ) => 
            if (loading) return <p>loading...</p>;
            if (error) return <Error erorr=error />;
            return (
              <div>
                <h2>You have orders.length === 0 ? 'no' : orders.length orderorders.length > 1 || orders.length === 0 ? 's' : ''.</h2>
                <OrderListItem 
                  orders=orders
                  urlReferer=urlReferer 
                  subscribeToNewOrders=() =>
                    subscribeToMore(
                      document: USER_ORDERS_SUBSCRIPTION,
                      variables: ,
                      updateQuery: (prev,  subscriptionData ) => 
                        if (!subscriptionData.data) return prev;
                        const newOrdertem = subscriptionData.data.order.node;
          
                        return Object.assign(, prev, 
                          orders: [newOrdertem, ...prev.orders]
                        );
                      
                    )
                   
                />
              </div>
            );
          
        </Query>

我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

原来解决方案是:

const options = 
  subscriptions: '/subscriptions',
;

然后调用服务器为:

  const wsLink = process.browser ? new WebSocketLink(
    uri: 'ws://localhost:4444/subscriptions',
  )

【讨论】:

以上是关于通过 apollo 连接到 graphql-yoga 服务器进行订阅的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

将 Angular 应用程序连接到多个 Apollo 客户端

react-apollo 没有连接到我的 graphql 本地服务器

使用替代 GraphQL 客户端连接到 Apollo Server

如何将 Gatsby 混合站点连接到 Apollo/Graphcool(或 Redux)?

设置 Redis cookie 时,Apollo 客户端未连接到服务器

如何在 React Native 中正确地将 Apollo 客户端连接到 Redux