Sidekiq perform_async 与 Apnotic(Apple 推送通知)

Sidekiq perform_async with Apnotic (Apple Push Notifications)

我在尝试异步 运行 Sidekiq worker 时收到此错误,当代码在主线程上 运行 时我没有收到此错误。

我正在尝试使用 Apnotic 向 iOS 应用程序发送推送通知。这是我的工人代码:

class ApnWorker
  include Sidekiq::Worker
  sidekiq_options queue: 'default'

  APNOTIC_POOL = Apnotic::ConnectionPool.new(...)

  def perform(notification) # Apnotic::Notification.new(device_token)
    APNOTIC_POOL.with do |connection|
      response = connection.push(notification)
      raise "APN Connection Timeout" unless response

      if response.status == "410" ||
        (response.status == "400" && response.body["reason"] == "BadDeviceToken")
        User.find_by(device_token: notification.token).update!(device_token: nil)
      end
    end
  end
end

这些作业随后失败,并最终出现在我的重试队列中。此错误显示为原因:

NoMethodError: undefined method `authorization=' for "#<Apnotic::Notification:0x000055e08470a980>"

我搜索了我的应用程序,但在任何地方都没有使用 authorization 这个词。最好的猜测是 Sidekiq 在我传递给他们的通知上调用 authorization=,但我很困惑为什么。

任何指导都会很有帮助。

更新

我发现了 authorization= 调用的来源,它是 Apnotic 准备推送通知的过程的一部分:

def prepare_request(notification)
  notification.authorization = provider_token if @auth_method == :token
  Apnotic::Request.new(notification)
end

所以我猜测 Sidekiq 调用的是不正确的,但这对解决方案没有多大帮助。 Apnotic::Notification 我发送我的工作人员是相同的,无论异步与否,他们都应该响应 authorization=,那么为什么异步会引发错误?

仍然非常坚持这一点。在此先感谢您的帮助。

问题与 Sidekiq 如何序列化您的 Apnotic::Notification 对象有关。文档建议您 don't pass complex objects as parameters to your sidekiq jobs。除了序列化通知对象,也许您可​​以将设备令牌传递给作业(假设它只是一个字符串)并将您的代码重写为:

def perform(device_token) 
  notification = Apnotic::Notification.new(device_token)
  APNOTIC_POOL.with do |connection|
    response = connection.push(notification)
    raise "APN Connection Timeout" unless response

    if response.status == "410" ||
      (response.status == "400" && response.body["reason"] == "BadDeviceToken")
      User.find_by(device_token: notification.token).update!(device_token: nil)
    end
  end
end

你可以用 apns_token 代替 device_token 吗?

使用 apns 或 voip 服务发送通知也很重要。