I'm trying to set up a graphcool subscription / websockets as per this tutorial at How To GraphQL but I'm getting the following message:
WebSocket connection to 'wss://subscriptions.graph.cool/v1/###' failed: WebSocket is closed before the connection is established.
I'm seem to have everything as per the tutorial. Do you have any idea why the websockets connection is not being established?
index.js
import React from 'react'
import ReactDOM from 'react-dom'
import App from './components/App'
import registerServiceWorker from './registerServiceWorker'
import './styles/index.css'
import { ApolloProvider, createNetworkInterface, ApolloClient } from 'react-apollo'
import { SubscriptionClient, addGraphQLSubscriptions } from 'subscriptions-transport-ws'
import { BrowserRouter } from 'react-router-dom'
import { GC_AUTH_TOKEN } from './constants'
const networkInterface = createNetworkInterface({
uri: 'https://api.graph.cool/simple/v1/###'
})
const wsClient = new SubscriptionClient('wss://subscriptions.graph.cool/v1/###', {
reconnect: true,
connectionParams: {
authToken: localStorage.getItem(GC_AUTH_TOKEN),
}
})
const networkInterfaceWithSubscriptions = addGraphQLSubscriptions(
networkInterface,
wsClient
)
networkInterface.use([{
applyMiddleware(req, next) {
if (!req.options.headers) {
req.options.headers = {}
}
const token = localStorage.getItem(GC_AUTH_TOKEN)
req.options.headers.authorization = token ? `Bearer ${token}` : null
next()
}
}])
const client = new ApolloClient({
networkInterface: networkInterfaceWithSubscriptions
})
ReactDOM.render(
<BrowserRouter>
<ApolloProvider client={client}>
<App />
</ApolloProvider>
</BrowserRouter>
, document.getElementById('root')
)
registerServiceWorker()
App.js
import React, { Component } from 'react'
import LinkList from './LinkList'
import CreateLink from './CreateLink'
import Header from './Header'
import Login from './Login'
import Search from './Search'
import { Switch, Route, Redirect } from 'react-router-dom'
class App extends Component {
render() {
return (
<div className='center w85'>
<Header />
<div className='ph3 pv1 background-gray'>
<Switch>
<Route exact path='/search' component={Search}/>
<Route exact path='/' component={LinkList}/>
<Route exact path='/create' component={CreateLink}/>
<Route exact path='/login' component={Login}/>
</Switch>
</div>
</div>
)
}
}
export default App
LinkList.js
import React, { Component } from 'react'
import Link from './Link'
import { graphql, gql } from 'react-apollo'
class LinkList extends Component {
_updateCacheAfterVote = (store, createVote, linkId) => {
const data = store.readQuery({ query: ALL_LINKS_QUERY })
const votedLink = data.allLinks.find(link => link.id === linkId)
votedLink.votes = createVote.link.votes
store.writeQuery({ query: ALL_LINKS_QUERY, data })
}
componentDidMount() {
this._subscribeToNewLinks()
this._subscribeToNewVotes()
}
render() {
if (this.props.allLinksQuery && this.props.allLinksQuery.loading) {
return <div>Loading</div>
}
if (this.props.allLinksQuery && this.props.allLinksQuery.error) {
return <div>Error</div>
}
const linksToRender = this.props.allLinksQuery.allLinks
return (
<div>
{linksToRender.map((link, index) => (
<Link key={link.id} updateStoreAfterVote={this._updateCacheAfterVote} index={index} link={link}/>
))}
</div>
)
}
_subscribeToNewLinks = () => {
this.props.allLinksQuery.subscribeToMore({
document: gql`
subscription {
Link(filter: {
mutation_in: [CREATED]
}) {
node {
id
url
description
createdAt
postedBy {
id
name
}
votes {
id
user {
id
}
}
}
}
}
`,
updateQuery: (previous, { subscriptionData }) => {
const newAllLinks = [
subscriptionData.data.Link.node,
...previous.allLinks
]
const result = {
...previous,
allLinks: newAllLinks
}
return result
}
})
}
_subscribeToNewVotes = () => {
this.props.allLinksQuery.subscribeToMore({
document: gql`
subscription {
Vote(filter: {
mutation_in: [CREATED]
}) {
node {
id
link {
id
url
description
createdAt
postedBy {
id
name
}
votes {
id
user {
id
}
}
}
user {
id
}
}
}
}
`,
updateQuery: (previous, { subscriptionData }) => {
const votedLinkIndex = previous.allLinks.findIndex(link => link.id === subscriptionData.data.Vote.node.link.id)
const link = subscriptionData.data.Vote.node.link
const newAllLinks = previous.allLinks.slice()
newAllLinks[votedLinkIndex] = link
const result = {
...previous,
allLinks: newAllLinks
}
return result
}
})
}
}
export const ALL_LINKS_QUERY = gql`
query AllLinksQuery {
allLinks {
id
createdAt
url
description
postedBy {
id
name
}
votes {
id
user {
id
}
}
}
}
`
export default graphql(ALL_LINKS_QUERY, { name: 'allLinksQuery' }) (LinkList)
Turns out the websocket endpoint was incorrect and is different for the Asia Pacific region wss://subscriptions.ap-northeast-1.graph.cool/v1/###