如何解决无法连接到 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 举报,一经查实,本站将立刻删除。