使用GraphQL Apollo跟踪在线用户

And*_*ura 8 websocket node.js apollo graphql apollo-server

我需要在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'
})
Run Code Online (Sandbox Code Playgroud)

但无法确定通过此套接字连接的用户.

我的实现:现在我让它像那样工作:

  1. 我们为所有调用表达了中间件,它将用户对象从jsonwebtoken推送到req对象.在这里,我可以触发"用户现在在线"的逻辑.

  2. 我已经创建了单独的订阅,客户端在登录时订阅它并在注销时取消订阅.由于没有取消订阅处理程序,我设法确定在没有有效负载的情况下在用户断开连接时调用过滤器函数,所以我采用了这种方法:

    userOnlineSubscription: {
        subscribe: withFilter(
            () => pubSub.asyncIterator('userOnlineSubscription'),
                async (payload, variables) => {
                    if (!payload) {
                        // set user offline
                }
                return false
            }
        )
    }
    
    Run Code Online (Sandbox Code Playgroud)

至于我,上面的解决方案是丑陋的.有人可以推荐更好的方法吗?

Med*_*uly 2

我用了这个方法

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'))
  })
}
Run Code Online (Sandbox Code Playgroud)