Apollo 订阅解析器永远不会激活?

Posted

技术标签:

【中文标题】Apollo 订阅解析器永远不会激活?【英文标题】:Apollo Subscription Resolver Never Activates? 【发布时间】:2017-12-03 13:01:48 【问题描述】:

我的组件正在调用订阅查询,但由于某种原因未访问订阅解析器:其中的断点从未激活。然而在客户端我收到 GraphQL 订阅错误:

“订阅必须返回 Async Iterable。收到:未定义”

这可能是什么原因造成的?

提前感谢大家提供任何信息。

订阅查询

const IM_SUBSCRIPTION_QUERY = gql`
      subscription getIMsViaSubscription($fromID: String!, $toID: String!)
          IMAdded(fromID:$fromID, toID: $toID)
            id,
            fromID,
            toID,
            msgText,
            myUserData
                id,
                name_first,
                name_last,
                picture_large,
                picture_medium,
                picture_thumbnail
                my_category
            
          
         
`;

解析器

Subscription: 
    IMAdded(IMThatWasAdded) 
        debugger; <== IS NEVER ACTIVATED
        subscribe: withFilter(() => SubscriptionServer.pubsub.asyncIterator(IM_ADDED_CHANNEL), (newIM, args) => 
            const callIsFromMsgFoldersComponent = args.toID == 0;
            var result;
            if (callIsFromMsgFoldersComponent)
                result = (newIM.fromID === args.fromID || newIM.toID === args.fromID);
             else 
                result = ((newIM.fromID === args.fromID && newIM.toID === args.toID) || (newIM.fromID === args.toID && newIM.toID === args.fromID));
            
            return result;
        )

组件

const withDataAndSubscription = graphql(GETIMS_QUERY, 
    options(toID) 
        console.log(GETIMS_QUERY);
        const fromID = Meteor.userId();
        return 
            fetchPolicy: 'cache-and-network',
            variables: fromID: `$fromID`, toID: `$toID`
        ;
    
    ,
    props: props => 
        debugger;
        return 
            loading: props.data.loading,
            instant_message: props.data.instant_message,
            subscribeToMore: props.data.subscribeToMore,
            subscribeToNewIMs: params => 
                debugger;  <==IS ACTIVATED AS EXPECTED
                console.log(IM_SUBSCRIPTION_QUERY); <==IS OKAY
                const fromID = Meteor.userId();
                const toID = params.toID;
                return props.data.subscribeToMore(
                    document: IM_SUBSCRIPTION_QUERY,
                    variables: fromID: `$fromID`, toID: `$toID`,
                    updateQuery: (previousResult, subscriptionData) => 
                        if (!subscriptionData.data) 
                            return previousResult;
                        
                        const newMsg = subscriptionData.data.createIM;
                        return update(previousResult, 
                            instant_message: 
                                $push: [newMsg],
                            ,
                        );
                    
                );
            
        ;
    ,
)
;

【问题讨论】:

您是否初始化了pubsub 服务的实例?您是否尝试过在服务器订阅功能中使用 console.log? 感谢您的意见。事实上,事实证明是需要更改的服务器设置。我将发布修复它的服务器端代码。 【参考方案1】:

自从我的帖子中的代码基于去年底的 Apollo 库以来,服务器端设置和突变/订阅解析器已经发生了很大变化。这是与当前 Apollo 库一起使用的代码,通过this tutorial:

服务器设置

import express from 'express';
import  graphqlExpress, graphiqlExpress  from 'graphql-server-express';
import bodyParser from 'body-parser';
import  cors  from 'cors';
import  execute, subscribe  from 'graphql';
import  createServer  from 'http';
import  SubscriptionServer  from 'subscriptions-transport-ws';

import schema from '/imports/api/schema';

//SET UP APOLLO QUERY / MUTATIONS / PUBSUB
const METEOR_PORT = 3000;
const GRAPHQL_PORT = 4000;
const server = express();

server.use('*', cors( origin: 'http://localhost:$METEOR_PORT' ));

server.use('/graphql', bodyParser.json(), graphqlExpress(
    schema
));

server.use('/graphiql', graphiqlExpress(
    endpointURL: '/graphql',
    subscriptionsEndpoint: `ws://localhost:$GRAPHQL_PORT/subscriptions`
));

// Wrap the Express server
const ws = createServer(server);
ws.listen(GRAPHQL_PORT, () => 
    console.log(`GraphQL Server is now running on http://localhost:$GRAPHQL_PORT`);
    // Set up the WebSocket for handling GraphQL subscriptions
    new SubscriptionServer(
        execute,
        subscribe,
        schema
    , 
        server: ws,
        path: '/subscriptions',
    );
);
//END OF SET UP APOLLO PUBSUB

突变解析器

   Mutation: 
        createIM(root, args, context) 
            var associatedUsers = [];
            associatedUsers.push(args.fromID);
            associatedUsers.push(args.toID);
            var IDofNewIM;

            return Promise.resolve()
                .then(() => 
                    const newIM = connectors.IMs.create(args);
                    return newIM;
                )
                .then(IMAdded => 
                    // publish subscription notification
                    pubsub.publish(IM_ADDED_CHANNEL,  IMAdded, args);
                    return IMAdded;
                )
                .catch((err)=> 
                    console.log(err);
                );
        ,

订阅解析器

IMAdded: 
    subscribe: withFilter(
        () => pubsub.asyncIterator(IM_ADDED_CHANNEL),
        (IMAdded, args) => 
            IMAdded = IMAdded.IMAdded;
            var result = ((IMAdded.fromID === args.fromID && IMAdded.toID === args.toID) || (IMAdded.fromID === args.toID && IMAdded.toID === args.fromID));
            return result;
        
    )
,

【讨论】:

以上是关于Apollo 订阅解析器永远不会激活?的主要内容,如果未能解决你的问题,请参考以下文章

Apollo 2.x:订阅解析器未触发?

GraphQL 字段的解析器没有被调用

调用 Boost JSON 解析器永远不会返回

Apollo GraphQL - 未触发解析器

无法理解 apollo-client 中解析器的使用

为接口编写 Apollo 解析器