如何关闭 Apollo 中 GraphQL 订阅的套接字连接
How to close socket connection for GraphQL subscription in Apollo
我想在用户注销后关闭我的 Apollo 服务器上的 GraphQL 订阅。最初的问题是我们是否应该在客户端或后端关闭此(套接字)连接。
在前端,我将 Angular 与 Apollo Client 一起使用,我通过从 apollo-angular
扩展 Subscription
class 来处理 GraphQL 订阅。我可以使用典型的 takeUntil
rxjs 实现关闭订阅频道:
this.userSubscription
.subscribe()
.pipe(takeUntil(this.subscriptionDestroyed$))
.subscribe(
({ data }) => {
// logic goes here
},
(error) => {
// error handling
}
);
但是,这不会关闭服务器上的 websocket,如果我是对的,这将导致订阅内存泄漏。
Apollo Server(和 express)为订阅设置的方式如下:
const server = new ApolloServer({
typeDefs,
resolvers,
subscriptions: {
onConnect: (connectionParams, webSocket, context) => {
console.log('on connect');
const payload = getAuthPayload(connectionParams.accessToken);
if (payload instanceof Error) {
webSocket.close();
}
return { user: payload };
},
onDisconnect: (webSocket, context) => {
console.log('on Disconnect');
}
},
context: ({ req, res, connection }) => {
if (connection) {
// set up context for subscriptions...
} else {
// set up context for Queries, Mutations...
}
当客户端注册一个新的 GraphQL 订阅时,我总是能在服务器日志上看到 console.log('on connect');
,但我从来没有看到 console.log('on Disconnect');
,除非我关闭前端应用程序。
我还没有看到任何关于如何使用 Apollo 关闭 websocket 订阅的例子。我这样做主要是为了完成一个Logout的实现。
我是不是漏掉了什么?提前致谢!
我在 Apollo 客户端 GitHub 站点上发布了 my solution 相关讨论。
我的解决方案基于此post
本质上,我们使用套接字创建订阅的方式是使用 subscriptions-transport-ws
export const webSocketClient: SubscriptionClient = new
SubscriptionClient(
`${environment.WS_BASE_URL}/graphql`,
{
reconnect: true,
lazy: true,
inactivityTimeout: 3000,
connectionParams: () => ({
params: getParams()
})
}
);
如问题中所述,我想在用户注销之前取消订阅所有频道并关闭订阅套接字连接。我们通过在注销函数中使用 webSocketClient
SubscriptionClient 并调用:
webSocketClient.unsubscribeAll();
webSocketClient.close();
我想在用户注销后关闭我的 Apollo 服务器上的 GraphQL 订阅。最初的问题是我们是否应该在客户端或后端关闭此(套接字)连接。
在前端,我将 Angular 与 Apollo Client 一起使用,我通过从 apollo-angular
扩展 Subscription
class 来处理 GraphQL 订阅。我可以使用典型的 takeUntil
rxjs 实现关闭订阅频道:
this.userSubscription
.subscribe()
.pipe(takeUntil(this.subscriptionDestroyed$))
.subscribe(
({ data }) => {
// logic goes here
},
(error) => {
// error handling
}
);
但是,这不会关闭服务器上的 websocket,如果我是对的,这将导致订阅内存泄漏。
Apollo Server(和 express)为订阅设置的方式如下:
const server = new ApolloServer({
typeDefs,
resolvers,
subscriptions: {
onConnect: (connectionParams, webSocket, context) => {
console.log('on connect');
const payload = getAuthPayload(connectionParams.accessToken);
if (payload instanceof Error) {
webSocket.close();
}
return { user: payload };
},
onDisconnect: (webSocket, context) => {
console.log('on Disconnect');
}
},
context: ({ req, res, connection }) => {
if (connection) {
// set up context for subscriptions...
} else {
// set up context for Queries, Mutations...
}
当客户端注册一个新的 GraphQL 订阅时,我总是能在服务器日志上看到 console.log('on connect');
,但我从来没有看到 console.log('on Disconnect');
,除非我关闭前端应用程序。
我还没有看到任何关于如何使用 Apollo 关闭 websocket 订阅的例子。我这样做主要是为了完成一个Logout的实现。
我是不是漏掉了什么?提前致谢!
我在 Apollo 客户端 GitHub 站点上发布了 my solution 相关讨论。
我的解决方案基于此post
本质上,我们使用套接字创建订阅的方式是使用 subscriptions-transport-ws
export const webSocketClient: SubscriptionClient = new
SubscriptionClient(
`${environment.WS_BASE_URL}/graphql`,
{
reconnect: true,
lazy: true,
inactivityTimeout: 3000,
connectionParams: () => ({
params: getParams()
})
}
);
如问题中所述,我想在用户注销之前取消订阅所有频道并关闭订阅套接字连接。我们通过在注销函数中使用 webSocketClient
SubscriptionClient 并调用:
webSocketClient.unsubscribeAll();
webSocketClient.close();