【问题标题】:Tracking online user with GraphQL Apollo使用 GraphQL Apollo 跟踪在线用户
【发布时间】:2018-06-28 12:41:22
【问题描述】:

我需要在 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'
})

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

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

  1. 我们有所有调用的 express 中间件,它将用户对象从 jsonwebtoken 推送到 req 对象。在这里我可以触发“用户现在在线”的逻辑。

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

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

对我来说,上面的解决方案很难看。有人可以推荐更好的方法吗?

【问题讨论】:

    标签: node.js websocket graphql apollo apollo-server


    【解决方案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'))
      })
    }
    

    【讨论】:

    • 不幸的是,这种方法“jsonwebtoken.verify”将被调用两次:在这个处理程序中和在graphQL订阅中。但我找不到更好的解决方案,所以它必须是公认的答案,因为它工作正常。
    猜你喜欢
    • 2018-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-19
    • 1970-01-01
    • 2010-12-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多