LoginSignup
1

More than 3 years have passed since last update.

Hasuraで「Error: Unable to find native implementation, or alternative implementation for WebSocket!」

Last updated at Posted at 2020-09-08

結論: WebSocketLinkはサーバーサイドでは使えない

  • SSRが問題
  • WebSocketLinkはブラウザで動作させて上げないといけない
  • WebSocketLinkがSSR時にサーバー側でエラーを起こしている
  • process.browserで判定してブラウザでのみWebSocketLinkを使う
import { ApolloClient, InMemoryCache } from "@apollo/client";
import { WebSocketLink } from "@apollo/client/link/ws";

const wsLink = process.browser ? new WebSocketLink({
    uri: "ws://localhost:8080/v1/graphql",
    options: {
      reconnect: true,
      connectionParams: {
        headers: {
        },
      },
    }
  }) : undefined;

const client = new ApolloClient({
  link: wsLink,
  cache: new InMemoryCache(),
});

前提

Hasura, Apollo, React, SSR(サーバーサイドレンダリング)
でGraphQLのSubscriptionsでリアルタイム更新をしたくてwebSocketを使った。

エラー内容


Error: Unable to find native implementation, or alternative implementation for WebSocket!

スクリーンショット 2020-09-08 23.13.58.png

解決

この実装ではエラーが出ます。

import { ApolloClient, InMemoryCache } from "@apollo/client";
import { WebSocketLink } from "@apollo/client/link/ws";

const wsLink = new WebSocketLink({
    uri: "ws://localhost:8080/v1/graphql",
    options: {
      reconnect: true,
      connectionParams: {
        headers: {
        },
      },
    },
  });

const client = new ApolloClient({
  link: wsLink,
  cache: new InMemoryCache(),
});

わるかったところ

結局SSRでサーバーサイドでのレンダリングをしている時に問題が起こっているようでした。
どうやらWebSocketはブラウザ側で動作させて上げないといけないらしい。

node.jsにもwsなるプラグインがあったので色々やれば動作するのかも知れないが

回避

process.browserでブラウザ動作かを判定して三項演算子でtrueならWebSocketLinkのインスタンスを返す。
falseなら返さないとしたいのでundefinedを返す

undefinedがいいかは分からなかったが、もっといい案があれば教えて下さい。

import { ApolloClient, InMemoryCache } from "@apollo/client";
import { WebSocketLink } from "@apollo/client/link/ws";

const wsLink = process.browser ? new WebSocketLink({
    uri: "ws://localhost:8080/v1/graphql",
    options: {
      reconnect: true,
      connectionParams: {
        headers: {
        },
      },
    }
  }) : undefined;

const client = new ApolloClient({
  link: wsLink,
  cache: new InMemoryCache(),
});

参考

GitHub
https://github.com/apollographql/subscriptions-transport-ws/issues/333#issuecomment-359261024

Hasura Subscription
https://hasura.io/learn/graphql/react/subscriptions/1-subscription/

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1