Skip to content

Struggling to make websockets work with vue-cli-plugin-apollo and Hasura #187

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
gitxav opened this issue Jul 23, 2019 · 1 comment
Closed

Comments

@gitxav
Copy link

gitxav commented Jul 23, 2019

Hi all:

I simply cannot get websockets to work with Hasura and Vue-cli-plugin-apollo.
In particular Vue Apollo stop complaining about missing websockets connection headers (at least explicitly) but it's now throwing the following error:

'Error: start received before the connection is initialised'.

I have in vue-apollo.js:

/* eslint-disable */
import Vue from 'vue'
import VueApollo from 'vue-apollo'
import { createApolloClient, restartWebsockets } from 'vue-cli-plugin-apollo/graphql-client'
import authService from './auth/authService'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { SubscriptionClient } from "subscriptions-transport-ws";

// Install the vue plugin
Vue.use(VueApollo)

// Name of the localStorage item
const AUTH_TOKEN = 'apollo-token'

// Http endpoint:     puedo poner 'https://vuejs-auth0-graphql.herokuapp.com/v1/graphql'
const httpEndpoint = 'https://vuejs-auth0-graphql.herokuapp.com/v1/graphql'
// Files URL root
export const filesRoot = 'https://vuejs-auth0-graphql.herokuapp.com'

Vue.prototype.$filesRoot = filesRoot

// Config
const defaultOptions = {
  // You can use `https` for secure connection (recommended in production)
  httpEndpoint,
  // You can use `wss` for secure connection (recommended in production)
  // Use `null` to disable subscriptions
  wsEndpoint: 'wss://vuejs-auth0-graphql.herokuapp.com/v1/graphql',
  // LocalStorage token
  tokenName: AUTH_TOKEN,
  // Enable Automatic Query persisting with Apollo Engine
  persisting: false,
  // Use websockets for everything (no HTTP)
  // You need to pass a `wsEndpoint` for this to work
  websocketsOnly: false,
  // Is being rendered on the server?
  ssr: false,

  // Override default apollo link
  // note: don't override httpLink here, specify httpLink options in the
  // httpLinkOptions property of defaultOptions.
  // link: myLink

  // Override default cache
  cache: new InMemoryCache({ freezeResults: false }),
  // cache: new InMemoryCache(),

  // Override the way the Authorization header is set
  // getAuth: (tokenName) => ...

  // Additional ApolloClient options
  // apollo: { ... }

  // Client local data (see apollo-link-state)
  // clientState: { resolvers: { ... }, defaults: { ... } }
  getAuth: tokenName => {
    // get the authentication token from local storage if it exists
    // return the headers to the context so httpLink can read them
    const token = localStorage.getItem('apollo-token')
    if (token) {
      return 'Bearer ' + token
    } else {
      return ''
    }
  },
}

// Call this in the Vue app file
export function createProvider (options = {}) {
  // Create apollo client
  const { apolloClient, wsClient } = createApolloClient({
    ...defaultOptions,
    ...options
  })

  wsClient.lazy = true
  wsClient.reconnect = true

  // Override connection params
		wsClient.connectionParams = () => {
		  const authorization = getAuth(tokenName)
		  return authorization ? { headers: { authorization } } : {}
		}

  // Set apollo client's websocket client
  apolloClient.wsClient = wsClient

  // Create vue apollo provider
  const apolloProvider = new VueApollo({
    defaultClient: apolloClient,
    defaultOptions: {
      $query: {
        //fetchPolicy: 'cache-and-network',
      }
    },
    errorHandler (error) {
      // eslint-disable-next-line no-console
      console.log('%cError', 'background: red; color: white; padding: 2px 4px; border-radius: 3px; font-weight: bold;', error.message)
    }
  })

  return apolloProvider
}

// las otras opciones son no usar plugin completo y editar vue apollo plugin

// Manually call this when user log in
export async function onLogin (apolloClient, token) {
  if (typeof localStorage !== 'undefined' && token) {
    localStorage.setItem(AUTH_TOKEN, token)
  }
  if (apolloClient.wsClient) restartWebsockets(apolloClient.wsClient)
  try {
    await apolloClient.resetStore()
  } catch (e) {
    // eslint-disable-next-line no-console
    console.log('%cError on cache reset (login)', 'color: orange;', e.message)
  }
}

// Manually call this when user log out
export async function onLogout (apolloClient) {
  if (typeof localStorage !== 'undefined') {
    localStorage.removeItem(AUTH_TOKEN)
  }
  if (apolloClient.wsClient) restartWebsockets(apolloClient.wsClient)
  try {
    await apolloClient.resetStore()
  } catch (e) {
    // eslint-disable-next-line no-console
    console.log('%cError on cache reset (logout)', 'color: orange;', e.message)
  }
}

I don't understand why is failing the websockets connection.

Please help me to find what is missing.
Thanks for your time.

@dohomi
Copy link

dohomi commented Sep 16, 2019

this is a bug and an open PR is in place: #144

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants