当我尝试使用URQL来订阅时,遇到了WebSocket协议不匹配的问题
首先
我曾经尝试使用URQL中的GraphQL订阅功能,但结果没有显示出来,这个错误困扰了我很长时间,所以我想留下来,以防同样的受害者再次遭遇这个问题。
简而言之
-
- サーバー(NestJS), クライアント(Next.js)をgraphql-wsで統一しても動作しない
subscriptions-transport-wsでは正常に動作する
环境
ツール・ライブラリ用途バージョンNext.jsフロントエンドとして利用12.1.6NestJSサーバーサイドとして利用8.4.6GraphQL Code Generatorコード自動生成ツール2.6.2URQLGraphQL Clientのライブラリ2.2.1node.jsフロント、サーバーサイドの実行環境v16.14.2
问题
由于在开头已经简单地写过课题的内容,所以接下来我将写下我遇到这个错误的经过。
首先,在使用GraphQL的订阅功能时,由于没有定义请求发送的协议,因此需要使用以下实现了在WebSocket上实现订阅功能的库之一。
-
- graphql-ws
- subscriptions-transport-ws
推荐使用graphql-ws作为其替代品,因为subscriptions-transport-ws没有进行积极的维护工作。
因此,我們遵循正式規範,選擇使用 graphql-ws。
然而,结果如下,既没有显示数据,也没有显示错误。
result:
data: undefined
error: undefined
extensions: undefined
fetching: false
operation: undefined
stale: false
顺便提一下,服务器端使用了NestJS进行实现,并且同时启用了graphql-ws和subscriptions-transport-ws两个选项。
※官方也允许同时使用这两个选项。
应对之策
在将URQL客户端的订阅WebSocket从graphql-ws更改为subscriptions-transport-ws后,它成功运行。
import {
createClient,
dedupExchange,
Exchange,
fetchExchange,
Provider,
} from 'urql'
import { authConfig } from '@/utils/urql/urql-auth-config'
import { graphCacheConfig } from '@/utils/urql/urql-graphcache-config'
import { subscriptionCustomExchange } from '@/utils/urql/urql-subscription-config'
export const urqlExchanges = [
dedupExchange,
cacheExchange(graphCacheConfig),
authExchange(authConfig),
fetchExchange,
subscriptionCustomExchange,
].filter(Boolean) as Exchange[]
const createUrqlClient = () =>
createClient({
url: 'http://localhost:8000/graphql',
suspense: true,
exchanges: urqlExchanges,
})
import { SubscriptionClient } from 'subscriptions-transport-ws'
import { Exchange, subscriptionExchange } from 'urql'
const isSSR = typeof window === 'undefined'
console.log({ isSSR })
const transportWsClient = !isSSR
? new SubscriptionClient('ws://localhost:8000/graphql', { reconnect: true })
: undefined
export const subscriptionCustomExchange: Exchange | null = transportWsClient
? subscriptionExchange({
forwardSubscription: operation => {
return transportWsClient.request(operation)
},
})
: null
闲聊
就像这里所写的一样,我们将graphql-ws库的子协议称为graphql-transport-ws,将subscriptions-transport-ws库的子协议称为graphql-ws。
真是一件相当复杂的事情,哈哈。

由于公式文件中明确指出,由于缺乏积极维护,该方法已被不推荐使用。因此,我们将继续调查何时能够使用graphql-ws。
再见!
请提供更多上下文信息,以便我准确地回答你的问题。 “参考記事” 在这里可以有几种不同的意思。如果您提供更多细节,我将很高兴为您提供一个合适的翻译。