您如何知道恢复登录尝试何时进行或已完成?

How do you know when a resume login attempt is being made or was completed?

客户端:

  1. 您能否在页面加载时判断是否会进行恢复登录尝试?
  2. 尝试returns时是否有钩子?我可以收听正确的 DDP 消息吗?

编辑:看起来 Meteor.userId() 是在页面加载时定义的,当将进行恢复登录尝试时,它负责 #1。

检查 Meteor.loggingIn()。如果您想知道用户是否正在尝试登录。 docs

这里有几个解决方案:

在客户端观看 DDP

不幸的是,当使用登录方法的结果调用流处理程序时,Meteor.connection._methodInvokers 已被清除 - 因此搜索功能。如果有不同的/更有效的方式来了解 resumeMethodId,那就太好了。几种可能性:

  • 是否保证有id"1"
  • 当 Meteor 决定调用登录时调用的钩子
  • 如果 Meteor.connection._methodInvokers 是被动的,我可以执行一个在找到 id 后停止的自动运行。

.

resumeAttemptComplete = (success) ->
  console.log 'resumeAttemptComplete', success

resumeMethodId = null

searchForResumeMethodId = ->
  for id, invoker of Meteor.connection._methodInvokers
    sentMessage = invoker._message
    if sentMessage.method is 'login' and sentMessage.params[0].resume?
      resumeMethodId = id

if Meteor.isClient
  Meteor.connection._stream.on 'message', (messageString) ->
    unless resumeMethodId
      searchForResumeMethodId()

    message = JSON.parse messageString

    if message.id is resumeMethodId and message.msg is 'result'
      resumeAttemptComplete !message.error

_methodInvokers 定义:https://github.com/meteor/meteor/blob/de74f2707ef34d1b9361784ecb4aa57803d34ae8/packages/ddp-client/livedata_connection.js#L79-L83

服务器 onLogin 向客户端发送事件

// server:

// map of connection ids -> publish function contexts
let onResumePublishers = {}

Meteor.publish('onResume', function () {
  onResumePublishers[this.connection.id] = this

  this.ready()

  this.onStop(() => {
    delete onResumePublishers[this.connection.id]
  })
})

let handleLoginEvent = function({connection, type}, loggedIn) {
  if (type === 'resume') {
    let publisher = onResumePublishers[connection.id]
    if (publisher)
      publisher.added('onResume', connection.id, {loggedIn}})
  }
}

Accounts.onLogin(function (loginAttempt) {
  handleLoginEvent(loginAttempt, true)
})

Accounts.onLoginFailure(function (loginAttempt) {
  handleLoginEvent(loginAttempt, false)
})

// client: 

let resumeExpires = new Date(localStorage.getItem('Meteor.loginTokenExpires'))
let resumeAttemptBeingMade = resumeExpires && resumeExpires > new Date()

let OnResume = new Mongo.Collection('onResume')

let onResumeSubscription = Meteor.subscribe('onResume')

OnResume.find(Meteor.connection.id).observeChanges(
  added(id, {loggedIn}) {
    onResumeSubscription.stop()
    onResumeAttemptCompleted(loggedIn)
  }
})

let onResumeAttemptCompleted = function(success) {
  // ...
}