Подписки Apollo — Nextjs — Ошибка: Observable преждевременно отменен на Concast.removeObserver

Я пытаюсь использовать подписку apollo/graphql в своем проекте nextjs, мой сервер graphql размещен во внешней службе nextjs, я могу без проблем работать с запросами и мутациями, но когда я использую реализацию useSubscription, я получаю следующую ошибку:

"Error: Observable cancelled prematurely at Concast.removeObserver (webpack-internal:///../../node_modules/@apollo/client/utilities/observables/Concast.js:118:33) at eval (webpack-internal:///../../node_modules/@apollo/client/utilities/observables/Concast.js:21:47) at cleanupSubscription (webpack-internal:///../../node_modules/zen-observable-ts/module.js:92:7) at Subscription.unsubscribe (webpack-internal:///../../node_modules/zen-observable-ts/module.js:207:7) at cleanupSubscription (webpack-internal:///../../node_modules/zen-observable-ts/module.js:97:21) at Subscription.unsubscribe (webpack-internal:///../../node_modules/zen-observable-ts/module.js:207:7) at eval (webpack-internal:///../../node_modules/@apollo/client/react/hooks/useSubscription.js:106:26) at safelyCallDestroy (webpack-internal:///../../node_modules/react-dom/cjs/react-dom.development.js:22763:5) at commitHookEffectListUnmount (webpack-internal:///../../node_modules/react-dom/cjs/react-dom.development.js:22927:11) at invokePassiveEffectUnmountInDEV (webpack-internal:///../../node_modules/react-dom/cjs/react-dom.development.js:24998:13) at invokeEffectsInDev (webpack-internal:///../../node_modules/react-dom/cjs/react-dom.development.js:27137:11) at commitDoubleInvokeEffectsInDEV (webpack-internal:///../../node_modules/react-dom/cjs/react-dom.development.js:27110:7) at flushPassiveEffectsImpl (webpack-internal:///../../node_modules/react-dom/cjs/react-dom.development.js:26860:5) at flushPassiveEffects (webpack-internal:///../../node_modules/react-dom/cjs/react-dom.development.js:26796:14) at eval (webpack-internal:///../../node_modules/react-dom/cjs/react-dom.development.js:26592:9) at workLoop (webpack-internal:///../../node_modules/scheduler/cjs/scheduler.development.js:266:34) at flushWork (webpack-internal:///../../node_modules/scheduler/cjs/scheduler.development.js:239:14) at MessagePort.performWorkUntilDeadline (webpack-internal:///../../node_modules/scheduler/cjs/scheduler.development.js:533:21)"

Я знаю, что сервер подписок работает правильно, потому что я могу слушать из студии Apollo, и я создал спа-центр с приложением create-реагировать, и он отлично работает.

Я использовал:

Сервер:

  • "аполло-сервер-экспресс": "^3.6.7"
  • "graphql-ws": "^5.7.0"

Клиент

  • "следующий": "^12.1.5"
  • "@аполло/клиент": "^3.5.10"
  • "graphql-ws": "^5.7.0"

Реализация хука

const room = useSubscription(
    gql`
      subscription onRoomAdded($roomAddedId: ID!) {
        roomAdded(id: $roomAddedId) {
          id
          name
        }
      }
    `
  );

Реализация клиента

import { ApolloClient, HttpLink, InMemoryCache, split } from '@apollo/client';
import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
import { getMainDefinition } from '@apollo/client/utilities';
import { createClient } from 'graphql-ws';
import fetch from 'isomorphic-fetch';

const HOST = 'http://localhost:3001/graphql';
const HOST_WS = 'ws://localhost:3001/graphql';
const isServer = typeof window === 'undefined';

if (isServer) {
  global.fetch = fetch;
}

const httpLink = new HttpLink({
  uri: HOST,
});

const link = isServer
  ? httpLink
  : split(
      ({ query }) => {
        const definition = getMainDefinition(query);
        return (
          definition.kind === 'OperationDefinition' &&
          definition.operation === 'subscription'
        );
      },
      new GraphQLWsLink(
        createClient({
          url: HOST_WS,
        })
      ),
      httpLink
    );

const client = new ApolloClient({
  ssrMode: isServer,
  link,
  cache: new InMemoryCache(),
});

export default client;

любая идея о проблеме? Я думаю, проблема может заключаться в том, что NextJS работает только с подписками-транспортом-ws, но в официальной документации по аполлону указано, что новый официальный способ - использовать graphql-ws, другая библиотека уже не поддерживается

ОБНОВИТЬ! Я проверил, что подписки работают правильно в производственной сборке, я изучаю, как реализовать их в процессе разработки. любые предложения приветствуются.

3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
2
0
257
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если он работает в производстве, но не в разработке, у вас может быть та же проблема, что и у меня с моим React SPA: StrictMode и двойной рендеринг как описано в этой проблеме github. Пока я нашел 2 способа заставить его работать:

  1. удалить StrictMode
  2. подпишитесь на vanilla JS вместоuseSubscription
const ON_USER_ADDED = gql`
  subscription OnUserAdded {
    userAdded {
      name
      id
    }
  }
`;

const subscribe = () => {
client.subscribe({
  query: ON_USER_ADDED,
}).subscribe({
    next(data) {
      console.log('data', data);
    },
    complete(){
      console.log('complete');
    },
    error(err) {
      console.log('error', err);
    }
  })
};

В моем случае у меня были проблемы с React StrictMode, большое спасибо, да пребудет с вами Сила ?

rrios 26.04.2022 12:17

useSubscription работает для меня

Weijing Jay Lin 06.05.2022 04:31

Другие вопросы по теме