未处理的 GraphQL 订阅错误,在 Angular 聊天组件中使用 apollos subscribeToMore 方法进行订阅时

问题描述

问题描述

我有一个 angular 聊天组件,它通过 graphql 查询从后端获取消息。 在同一个查询中,我订阅了通过 graphql 突变添加新消息时的更新。

消息订阅被编码为聊天组件的一个方法,以便我可以在组件第一次呈现时在 angular 生命周期方法中调用它。

根据 apollo 中的文档,这是订阅的常用设置: https://apollo-angular.com/docs/data/subscriptions

当我调用将订阅编码到其中的方法时,出现以下错误:

“不能使用来自另一个模块或领域的 GraphQLSchema“[object GraphQLSchema]”。 确保 node_modules 中只有一个“graphql”实例 目录。如果不同版本的“graphql”是其他版本的依赖 依赖于模块,使用“分辨率”来确保只安装一个版本。 https://yarnpkg.com/en/docs/selective-version-resolutions 不能同时使用重复的“graphql”模块,因为不同 版本可能具有不同的功能和行为。数据来自一 另一个函数中使用的版本可能会产生混淆和 虚假结果。”

我知道错误来自该方法的调用,当我注释掉调用时,错误消失了。 订阅不查询后端,所以我知道问题出在客户端。

预期行为

当用户在聊天中发送新消息时,服务器会通知订阅解析器(服务器端)发生了消息更新,它会将所有消息实时回火到前端,并且消息应该通过subscribe to more方法返回。

我为解决此问题而采取的步骤

我试着看看这个问题: Duplicate "graphql" modules cannot be used

这让我找到了这个链接: https://github.com/graphql/graphql-js/issues/491

对于使用 yarn 作为包管理器的人来说,有一个解决方法,但我不关心,因为我使用的是 npm。

我想可能有一个重复的 graphql 模块,所以我尝试清理我的 package.json 文件,删除节点模块并重新安装它们,但没有奏效。

代码示例

聊天组件

import { Component,OnInit } from '@angular/core';
import { Apollo,QueryRef,gql } from 'apollo-angular';

const MESSAGES_SUBSCRIPTION = gql`
   subscription {
     messagesAdded {
      id
      content
      user
    }
  }
`;

const GET_MESSAGES = gql`
   query messages{
     messages {
      id
      content
      user
    }
  } `;


 const POST_MESSAGE = gql`
   mutation($user: String!,$content: String!) {
           postMessage(user: $user,content: $content)
   }`;

export class ChatComponent implements OnInit {

 msgsQuery: QueryRef<any>;
 isShowen: boolean = false;  
 isMinimized: boolean = false;
 msgs: any;
 content:String = '';

 constructor(private apollo: Apollo) {
  this.msgsQuery = this.apollo.watchQuery({
    query: GET_MESSAGES
  });

  this.msgsQuery.valueChanges
  .subscribe(({data}:any) => {
    this.msgs = data.messages;
  });
 }

 ngOnInit(): void {
   //this.subscribeToNewMsgs(); //Error is logged when invoked
 }

 subscribeToNewMsgs() {
   this.msgsQuery.subscribeToMore({
    document: MESSAGES_SUBSCRIPTION,updateQuery: (prev,{subscriptionData}) => {
     if (!subscriptionData.data) {
       return prev;
     }

     const newMsgs = subscriptionData.data.messages;
     console.log(newMsgs)

     return {
      entry: {
        msgs: [...newMsgs,...prev.entry.messages]
      }
     };
    }
  });
 }

 sendMsg(){
  this.apollo.mutate({
    mutation: POST_MESSAGE,variables: {
      user: 'Test',content: this.content
    }
  }).subscribe(({ data }) => {
    console.log('got data',data);
  },(error) => {
    console.log('there was an error sending the query',error);
  });
 }

}

依赖于 package.json 文件

{  
 "dependencies": {
    "@angular/animations": "~10.1.3","@angular/common": "~10.1.3","@angular/compiler": "~10.1.3","@angular/core": "~10.1.3","@angular/forms": "~10.1.3","@angular/platform-browser": "~10.1.3","@angular/platform-browser-dynamic": "~10.1.3","@angular/router": "~10.1.3","@apollo/client": "^3.3.3","@cloudinary/angular-5.x": "^1.3.3","apollo-angular": "^2.2.0","apollo-angular-link-http": "^1.11.0","apollo-cache-inmemory": "^1.6.6","apollo-utilities": "^1.3.4","cloudinary-core": "^2.11.3","graphql": "^15.4.0","ng-image-slider": "^2.6.4","ng2-file-upload": "^1.4.0","react": "^17.0.1","rxjs": "~6.6.0","subscriptions-transport-ws": "^0.9.18","tslib": "^2.0.0","zone.js": "~0.10.2"
 },}

客户端订阅设置根据 apollo 文档进行编码: [查看客户端设置] (https://apollo-angular.com/docs/data/subscriptions)

我没有包含服务器端代码,因为 subscribeToMore 在发送新消息时从不发回数据,因为它遇到了所描述的错误。 我使用的是 Angular v 10.1.6。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...