ostinelli / apnotic

A Ruby APNs HTTP/2 gem able to provide instant feedback.
MIT License
480 stars 96 forks source link

Correct structuring of sending push notifications from an instance? #43

Closed AndrewHartAR closed 7 years ago

AndrewHartAR commented 7 years ago

I'd have an instance which is kept around for the lifetime of my application, and I'd like to have a single connection be open. I've been playing with the code, and I'm not sure where the @connection.join line should go, or if it's even required - my app seems to function fine without it. It actually didn't perform as well when following each push notification, but that just may be push notification performance (it's always hard to say). Also, are there any problems in the way my code is setup?

I appreciate your support.

class PushNotificationManager
  def initialize()
    # create a persistent connection
    if development
      @connection = Apnotic::Connection.development(cert_path: "PushCertDev.pem")
    else
      @connection = Apnotic::Connection.new(cert_path: "PushCertDist.pem")
    end
    # wait for all requests to be completed
    # @connection.join
  end

  def clean_up
    # close the connection
    @connection.close
  end

  def send_message_to_device(message, device_token)
    # Sends the message asynchronously
    # If this causes problems then it can be done synchronously instead

    notification = Apnotic::Notification.new(device_token)
    notification.alert = {
      title: message.from_user_name,
      body: message.text,
      action: 'View'
    }
    notification.content_available = true
    notification.category = 'new'
    notification.custom_payload = {
      text: message.text,
      message_id: message.message_id,
      from_user_id: message.from_user_id,
      to_user_id: message.to_user_id
    }
    notification.topic = 'ProjectDent.TwIMTopic'

    # prepare push
    push = @connection.prepare_push(notification)
    push.on(:response) do |response|
      reason = nil

      if response.body.class == Hash
        reason = response.body['reason']
      end

      if response.ok?
        yield true, reason
        # Reason is logged - may be nil, but just in case there is ever a reason while still saying it's ok.
        TwIMLog.log('push notification', "sent notification with message id: #{message.message_id}, to device with token: #{device_token}, reason: #{reason}")
      else
        yield false, reason
        TwIMLog.log('push notification', "failed to send notification with message id: #{message.message_id}, to device with token: #{device_token}, reason: #{reason}")
      end
    end

    # send
    @connection.push_async(push)
  end
end
ostinelli commented 7 years ago

join is only needed if you want your code to wait for all outstanding requests.

For the rest, note that the recommended wait to use Apnotic is clearly specified in the README and it includes a queue manager, as per the provided example.

Hope this clear up.