Skip to content

Commit

Permalink
transport: implement graphql-transport-ws ws sub-protocol (#1507)
Browse files Browse the repository at this point in the history
* websocket: create `messageExchanger` to handle subprotocol messages

* remove unused type

* typo in comments

* change `graphqlwsMessageType` type to string

* add support for `graphql-transport-ws` subprotocol

* fix chat app example

* update example chat app dependencies

* improve chat app exmaple to use the recommended ws library

* add tests

* removed unused const in tests

* Update example/chat/readme.md

Co-authored-by: Jared Forsyth <jabapyth@gmail.com>
Signed-off-by: Steve Coffman <steve@khanacademy.org>

Co-authored-by: Steve Coffman <StevenACoffman@users.noreply.github.com>
Co-authored-by: Jared Forsyth <jabapyth@gmail.com>
  • Loading branch information
3 people authored Nov 9, 2021
1 parent 28caa6c commit 828820a
Show file tree
Hide file tree
Showing 10 changed files with 651 additions and 95 deletions.
3 changes: 1 addition & 2 deletions example/chat/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@
"private": true,
"dependencies": {
"@apollo/client": "^3.2.3",
"@apollo/react-hooks": "^4.0.0",
"apollo-cache-inmemory": "^1.3.11",
"apollo-link-ws": "^1.0.10",
"apollo-utilities": "^1.0.26",
"graphql": "^14.0.2",
"graphql-tag": "^2.10.0",
Expand All @@ -18,6 +16,7 @@
},
"scripts": {
"start": "react-scripts start",
"start:graphql-transport-ws": "REACT_APP_WS_PROTOCOL=graphql-transport-ws npm run start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
Expand Down
20 changes: 17 additions & 3 deletions example/chat/readme.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
### chat app
# Chat App

Example app using subscriptions to build a chat room.

to run this server
### Server
```bash
go run ./server/server.go
```

to run the react app
### Client
The react app uses two different implementation for the websocket link
- [apollo-link-ws](https://www.apollographql.com/docs/react/api/link/apollo-link-ws) which uses the deprecated [subscriptions-transport-ws](https://github.com/apollographql/subscriptions-transport-ws) library
- [graphql-ws](https://github.com/enisdenjo/graphql-ws)

First you need to install the dependencies
```bash
npm install
```

Then to run the app with the `apollo-link-ws` implementation do
```bash
npm run start
```

or to run the app with the `graphql-ws` implementation (and the newer `graphql-transport-ws` protocol) do
```bash
npm run start:graphql-transport-ws
```
2 changes: 1 addition & 1 deletion example/chat/src/Room.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useState, useEffect, useRef } from 'react';
import gql from 'graphql-tag';
import { useQuery, useMutation } from '@apollo/react-hooks';
import { useQuery, useMutation } from '@apollo/client';
import { Chat, ChatContainer, Message, MessageReceived } from './components/room';

export const Room = ({ channel, name }) => {
Expand Down
46 changes: 46 additions & 0 deletions example/chat/src/graphql-ws.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { createClient } from 'graphql-ws';
import { print } from 'graphql';
import { ApolloLink, Observable } from '@apollo/client';

export class WebSocketLink extends ApolloLink {
client;

constructor(options) {
super();
this.client = createClient(options);
}

request(operation) {
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) {
return sink.error(err);
}

if (err instanceof CloseEvent) {
return sink.error(
// reason will be available on clean closes
new Error(
`Socket closed with event ${err.code} ${err.reason || ''}`,
),
);
}

return sink.error(
new Error(
err
.map(({ message }) => message)
.join(', '),
),
);
},
},
);
});
}
}
24 changes: 16 additions & 8 deletions example/chat/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,24 @@ import {
split,
} from '@apollo/client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { WebSocketLink } from 'apollo-link-ws';
import { WebSocketLink as ApolloWebSocketLink} from '@apollo/client/link/ws';
import { getMainDefinition } from 'apollo-utilities';
import { App } from './App';

const wsLink = new WebSocketLink({
uri: `ws://localhost:8085/query`,
options: {
reconnect: true
}
});
import { WebSocketLink as GraphQLWSWebSocketLink } from './graphql-ws'

let wsLink;
if (process.env.REACT_APP_WS_PROTOCOL === 'graphql-transport-ws') {
wsLink = new GraphQLWSWebSocketLink({
url: `ws://localhost:8085/query`
});
} else {
wsLink = new ApolloWebSocketLink({
uri: `ws://localhost:8085/query`,
options: {
reconnect: true
}
});
}

const httpLink = new HttpLink({ uri: 'http://localhost:8085/query' });

Expand Down
Loading

0 comments on commit 828820a

Please sign in to comment.