我需要在GraphQL Apollo Node.js服务器上处理“用户现在在线”和“用户现在离线”的事件。最好的方法是什么?
我的调查:我非常确定我不需要实现任何心跳逻辑,因为订阅正在处理WebSockets。但我没有在他们的文档中找到任何信息如何处理WebSockets事件,如“连接”和“断开”订阅...实际上我可以从实际订阅的外部处理这些事件:
SubscriptionServer.create({
execute,
subscribe,
schema,
onConnect = (...args) => {
console.log('User connected')
},
onDisconnect = (...args) => {
console.log('User disconnected')
}
}, {
server: ws,
path: '/subscriptions'
})
但无法确定通过此套接字连接了哪个用户。
我的实施:现在我的工作就是这样:
我们为所有调用都表达了中间件,它将用户对象从jsonwebtoken推送到req
对象。在这里,我可以触发“用户现在在线”逻辑。
我创建了单独的订阅,客户端在登录时订阅它并取消订阅注销。由于没有取消订阅处理程序,我设法确定在没有负载的情况下在用户断开连接时调用过滤器函数,所以我采用了这种方法:
userOnlineSubscription: {
subscribe: withFilter(
() => pubSub.asyncIterator('userOnlineSubscription'),
async (payload, variables) => {
if (!payload) {
// set user offline
}
return false
}
)
}
至于我,上面的解决方案很难看。有人可以推荐更好的方法吗?
答案 0 :(得分:1)
我使用了这种方法
onConnect (connectionParams, webSocket) {
const userPromise = new Promise((resolve, reject) => {
if (connectionParams.jwt) {
jsonwebtoken.verify(
connectionParams.jwt,
JWT_SECRET,
(err, decoded) => {
if (err) {
reject(new Error('Invalid Token'))
}
resolve(
User.findOne({
where: { id: decoded.id }
})
)
}
)
} else {
reject(new Error('No Token'))
}
})
return userPromise.then(user => {
if (user) {
return { user: Promise.resolve(user) }
}
return Promise.reject(new Error('No User'))
})
}