无法连接到 Graphql 订阅?
Posted
技术标签:
【中文标题】无法连接到 Graphql 订阅?【英文标题】:Trouble connecting to Graphql subscriptions? 【发布时间】:2021-09-11 05:55:46 【问题描述】:我已关注 Apollo 文档,但似乎仍然在连接订阅时遇到问题。这是我的代码:在前端,我可以看到它正在尝试连接但正在记录: WebSocket 连接到 'ws://localhost:4000/subscriptions' 失败: 我一直在关注这个: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, res, connection) =>
const user = req.user;
return models, SECRET, 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`);
);
);
任何帮助将不胜感激......
【问题讨论】:
【参考方案1】:我在服务器中看不到创建 websocket 的声明。比如:
const WebSocket = require('ws');
const graphQLWebSocket = new WebSocket.Server(noServer: true);
然后也输入:
server.installSubscriptionHandlers(graphQLWebSocket);
在server.applyMiddleware( app );
的行之后
更多信息here。
【讨论】:
以上是关于无法连接到 Graphql 订阅?的主要内容,如果未能解决你的问题,请参考以下文章
SQL2008订阅发布,进程无法连接到 Subscriber
Apollo 客户端无法连接到 GraphQL 服务器(http 调用执行失败)