如何创建基本客户端以通过 websockets 使用 GraphQL 订阅
Posted
技术标签:
【中文标题】如何创建基本客户端以通过 websockets 使用 GraphQL 订阅【英文标题】:How to create a basic client to use GraphQL subscriptions via websockets 【发布时间】:2020-06-28 15:58:49 【问题描述】:我正在尝试创建一个类似聊天的基本应用,只是为了学习一些东西。
我已经设置了一个基本的 graphql 服务器来处理连接用户,并让他们添加一条消息。现在我正在尝试添加一些机制,以便每个用户都可以实时看到彼此添加的消息。我是 GraphQL 新手,但我应该使用订阅。
这是我的服务器 index.ts:
import createServer from 'http';
import jwt from 'jsonwebtoken';
import mongoose from 'mongoose';
import resolvers from 'modules/resolvers';
import typeDefs from 'modules/type-defs';
import ApolloServer from 'apollo-server-express';
import cookieParser from 'cookie-parser';
import express from 'express';
import cors from 'cors';
const PORT = 4000;
const getUser = (token: string) =>
// ...
;
const server = new ApolloServer(
context: ( req, res ) =>
const token = req.cookies.jwt;
const currentUser = getUser(token);
return currentUser, req, res ;
,
resolvers,
subscriptions:
onConnect: async (connectionParams, webSocket, context) =>
console.log(`Subscription client connected using Apollo server's built-in SubscriptionServer.`)
,
onDisconnect: async (webSocket, context) =>
console.log(`Subscription client disconnected.`)
,
,
typeDefs,
);
const app = express();
const httpServer = createServer(app);
app.use(cors( credentials: true, origin: 'http://localhost:3000' ));
app.use(cookieParser());
server.applyMiddleware( app, cors: false );
server.installSubscriptionHandlers(httpServer);
httpServer.listen(PORT, () =>
console.log(`Server ready at http://localhost:$PORT$server.graphqlPath`);
console.log(`Subscriptions ready at ws://localhost:$PORT$server.subscriptionsPath`);
);
mongoose.connect('mongodb://127.0.0.1:27017/irc',
useCreateIndex: true,
useNewUrlParser: true,
useUnifiedTopology: true,
);
我要做的是在客户端(javascript/react)上设置一些尽可能简单的东西,而不必依赖像 apollo-client 这样的库。 我设法使用简单的 fetch 调用来发送查询/突变,并希望能够以“简单”的方式使用订阅。 Apollo-client 对于我正在尝试做的事情似乎过于复杂,我想了解它实际上是如何工作的 - 但每个关于订阅的教程似乎都使用这个库......
我不太了解我的服务器在订阅方面实际上做了什么,我以为我已经将它配置为监听 websockets 连接,但我不再那么确定了。
我尝试发送一条基本消息只是为了看看会发生什么:
const ws = new WebSocket('ws://localhost:4000/graphql');$
ws.onopen = event =>
ws.send('Lorem ipsum dolor sit amet.');
;
...但即使我的 chrome 的网络选项卡似乎表明一切正常,我的服务器似乎并不关心我的消息,因为没有任何记录。
有人可以解释一下是否可以使用基本的网络套接字来使用 apollo-server 的订阅?怎么做?
谢谢
【问题讨论】:
【参考方案1】:Apollo 服务器和 Apollo 客户端都在后台使用 subscriptions-transport-ws 来处理订阅。 subscriptions-transport-ws
使用 WebSocket 作为在服务器和客户端之间交换消息的传输。这些消息具有库使用的特定格式 - 为了在客户端使用 only WebSocket,您必须发送相同类型的消息。
您可以检查源代码以确定发送的消息类型和时间。不过,更好的选择是创建SubscriptionClient 的实例并利用其方法。由于该库的使用没有特别完善的文档,因此您必须自己摸索,但应该可以。
不过,如果您是 GraphQL 新手,您应该坚持使用 Apollo Client,因为它的文档相当不错(请参阅 here),而且订阅的设置可能非常复杂,尤其是在您添加身份验证之后。
【讨论】:
以上是关于如何创建基本客户端以通过 websockets 使用 GraphQL 订阅的主要内容,如果未能解决你的问题,请参考以下文章
如何使我的 websockets 客户端在代理服务器方面健壮?