微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

无法连接到 Graphql 订阅?

如何解决无法连接到 Graphql 订阅?

我已关注 Apollo 文档,但似乎仍然无法连接到订阅。这是我的代码:在前端,我可以看到它正在尝试连接但正在记录: 与“ws://localhost:4000/subscriptions”的 WebSocket 连接失败: 我一直在关注这个:https://www.apollographql.com/docs/apollo-server/data/subscriptions/ 但似乎文档有点落后,所以我可能会遗漏一些东西。

客户:

import ReactDOM from 'react-dom';
import './index.css';
import Routes from './routes';
import 'semantic-ui-css/semantic.min.css';
import { setContext } from '@apollo/client/link/context';
import { WebSocketLink } from '@apollo/client/link/ws';
import { getMainDeFinition } from '@apollo/client/utilities';

import { 
  ApolloProvider,ApolloClient,HttpLink,InMemoryCache,split,} from '@apollo/client';

// Http link
const httpLink = new HttpLink({ uri: 'http://localhost:4000/graphql' });

// Websocket link
const wsLink = new WebSocketLink({
  uri: 'ws://localhost:4000/subscriptions',options: {
    reconnect: true
  }
});

// Attach auth headers to requests
const middlewareLink = setContext((_,{ headers }) => {
  // get the authentication token from local storage if it exists
  const token = localStorage.getItem('token');
  const refreshToken = localStorage.getItem('refreshToken');

  // return the headers to the context so httpLink can read them
  return {
    headers: {
      ...headers,x_token: token ? `${token}` : "",x_refresh_token: refreshToken ? `${refreshToken}`: ""
    }
  }
});


// Combine
const httpLinkWithMiddleware = middlewareLink.concat(httpLink);

// Split link - either http or ws depending on graphql 
const splitLink = split(
  ({ query }) => {
    const deFinition = getMainDeFinition(query);
    return (
      deFinition.kind === 'OperationDeFinition' &&
      deFinition.operation === 'subscription'
    );
  },wsLink,httpLinkWithMiddleware,);

// Create client with link
const client = new ApolloClient({
  link: splitLink,cache: new InMemoryCache(),});

// Provide client
const App = (
  <ApolloProvider client={client}>
    <Routes />
  </ApolloProvider>
)

// Render
ReactDOM.render(
  App,document.getElementById('root')
);

服务器:

import express from 'express';
import path from 'path';
import { fileLoader,mergeTypes,mergeResolvers } from 'merge-graphql-schemas';
import { ApolloServer } from 'apollo-server-express';
import { refreshTokens } from './auth';
import models from './models';
import cors from 'cors';
import jwt from 'jsonwebtoken';

const SECRET = "";
const SECRET2 = "";

const typeDefs = mergeTypes(fileLoader(path.join(__dirname,'./schema')));
const resolvers = mergeResolvers(fileLoader(path.join(__dirname,'./resolvers')));

const PORT = 4000;
const app = express();

// Cors
app.use(cors('*'));

// Add tokens
const addUser = async (req,res,next) => {
  const token = req.headers['x_token'];
  if (token) {
    try {
      const { user } = jwt.verify(token,SECRET);
      req.user = user;
    } catch (err) {
      const refreshToken = req.headers['x_refresh_token'];
      const newTokens = await refreshTokens(token,refreshToken,models,SECRET,SECRET2);
      if (newTokens.token && newTokens.refreshToken) {
        res.set('Access-Control-Expose-Headers','x_token','x_refresh_token');
        res.set('x_token',newTokens.token);
        res.set('x_refresh_token',newTokens.refreshToken);
      }
      req.user = newTokens.user;
    }
  }
  next();
};

app.use(addUser);

// Create server
const server = new ApolloServer({
   typeDefs,resolvers,subscriptions: {
     path: '/subscriptions'
   },context: ({req,connection}) => { 
     const user = req.user;
     return { models,SECRET2,user }; 
    },});

// Apply middleware
server.applyMiddleware({ app });

// Sync and listen
models.sequelize.sync({force: true}).then(x => {
  app.listen({ port: PORT },() => {
    console.log(`? Server ready at http://localhost:${PORT}${server.graphqlPath}`);
    console.log(`? Subscriptions ready at ws://localhost:${PORT}${server.subscriptionsPath}`);
  }
  );
});

任何帮助将不胜感激...

解决方法

我在服务器中看不到声明 websocket 创建。类似的东西:

const WebSocket = require('ws');
const graphQLWebSocket = new WebSocket.Server({noServer: true});

然后也输入:

server.installSubscriptionHandlers(graphQLWebSocket);

在带有 server.applyMiddleware({ app }); 的行之后

更多信息here

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。