From bd96571366c004ab59a17e50ba7fa27e8f777e99 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Thu, 3 Dec 2020 12:30:24 +0300 Subject: [PATCH 1/2] Use graphql-ws instead of subscriptions-transport-ws --- .../graphql-playground-react/package.json | 3 +- .../src/state/sessions/WebSocketLink.ts | 43 +++++++++++++++++++ .../src/state/sessions/fetchingSagas.ts | 11 ++--- 3 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 packages/graphql-playground-react/src/state/sessions/WebSocketLink.ts diff --git a/packages/graphql-playground-react/package.json b/packages/graphql-playground-react/package.json index cb94a232c..d3b607efa 100644 --- a/packages/graphql-playground-react/package.json +++ b/packages/graphql-playground-react/package.json @@ -112,7 +112,6 @@ "@types/lru-cache": "^4.1.1", "apollo-link": "^1.2.13", "apollo-link-http": "^1.5.16", - "apollo-link-ws": "^1.0.19", "calculate-size": "^1.1.1", "codemirror": "^5.58.1", "codemirror-graphql": "^0.12.3", @@ -121,6 +120,7 @@ "cuid": "^1.3.8", "graphiql": "^0.17.5", "graphql": "^15.3.0", + "graphql-ws": "^2.0.1", "immutable": "^4.0.0-rc.9", "isomorphic-fetch": "^2.2.1", "js-yaml": "^3.10.0", @@ -157,7 +157,6 @@ "reselect": "^4.0.0", "seamless-immutable": "^7.0.1", "styled-components": "^4.0.0", - "subscriptions-transport-ws": "^0.9.5", "utility-types": "^1.0.0", "webpack-bundle-analyzer": "^3.3.2", "zen-observable": "^0.7.1" diff --git a/packages/graphql-playground-react/src/state/sessions/WebSocketLink.ts b/packages/graphql-playground-react/src/state/sessions/WebSocketLink.ts new file mode 100644 index 000000000..35df59b49 --- /dev/null +++ b/packages/graphql-playground-react/src/state/sessions/WebSocketLink.ts @@ -0,0 +1,43 @@ +import { ApolloLink, Operation, FetchResult, Observable } from 'apollo-link'; +import { print, GraphQLError } from 'graphql'; +import { Client } from 'graphql-ws'; + +export class WebSocketLink extends ApolloLink { + + constructor(private client: Client) { + super(); + } + + public request(operation: Operation): Observable { + return new Observable((sink) => { + return this.client.subscribe( + { ...operation, query: print(operation.query) }, + { + next: sink.next.bind(sink), + complete: sink.complete.bind(sink), + error: (err) => { + if (err instanceof Error) { + sink.error(err); + } else if (err instanceof CloseEvent) { + sink.error( + new Error( + `Socket closed with event ${err.code}` + err.reason + ? `: ${err.reason}` // reason will be available on clean closes + : '', + ), + ); + } else { + sink.error( + new Error( + (err as GraphQLError[]) + .map(({ message }) => message) + .join(', '), + ), + ); + } + }, + }, + ); + }); + } +} \ No newline at end of file diff --git a/packages/graphql-playground-react/src/state/sessions/fetchingSagas.ts b/packages/graphql-playground-react/src/state/sessions/fetchingSagas.ts index 43c8e5443..19aa6c18a 100644 --- a/packages/graphql-playground-react/src/state/sessions/fetchingSagas.ts +++ b/packages/graphql-playground-react/src/state/sessions/fetchingSagas.ts @@ -1,8 +1,8 @@ import { ApolloLink, execute } from 'apollo-link' import { parseHeaders } from '../../components/Playground/util/parseHeaders' -import { SubscriptionClient } from 'subscriptions-transport-ws' +import { createClient as createSubscriptionClient, Client as SubscriptionClient } from 'graphql-ws' import { HttpLink } from 'apollo-link-http' -import { WebSocketLink } from 'apollo-link-ws' +import { WebSocketLink } from './WebSocketLink' import { isSubscription } from '../../components/Playground/util/hasSubscription' import { takeLatest, @@ -77,10 +77,11 @@ export const defaultLinkCreator = ( return { link: httpLink } } - const subscriptionClient = new SubscriptionClient(subscriptionEndpoint, { - timeout: 20000, + const subscriptionClient = createSubscriptionClient({ + retryTimeout: 20000, lazy: true, connectionParams, + url: session.endpoint, }) const webSocketLink = new WebSocketLink(subscriptionClient) @@ -143,7 +144,7 @@ function* runQuerySaga(action) { const channel = eventChannel(emitter => { let closed = false if (subscriptionClient && operationIsSubscription) { - subscriptionClient.onDisconnected(() => { + subscriptionClient.on('closed', () => { closed = true emitter({ error: new Error( From 25bda68cdac2e2959f0166ba23ff1f0bc4f23ad5 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Thu, 3 Dec 2020 12:58:11 +0300 Subject: [PATCH 2/2] switch protocol from http to ws --- .../src/state/sessions/fetchingSagas.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/graphql-playground-react/src/state/sessions/fetchingSagas.ts b/packages/graphql-playground-react/src/state/sessions/fetchingSagas.ts index 19aa6c18a..68d4f4b02 100644 --- a/packages/graphql-playground-react/src/state/sessions/fetchingSagas.ts +++ b/packages/graphql-playground-react/src/state/sessions/fetchingSagas.ts @@ -81,7 +81,7 @@ export const defaultLinkCreator = ( retryTimeout: 20000, lazy: true, connectionParams, - url: session.endpoint, + url: session.endpoint.replace('http', 'ws'), }) const webSocketLink = new WebSocketLink(subscriptionClient)