5

Appleのプッシュサーバーへの接続を開き、保留中のすべての通知を送信するrubyスクリプトがあります。理由はわかりませんが、Appleがスクリプトを切断すると、パイプの破損エラーが発生します。私はこれに対応するためにスクリプトを作成しましたが、そもそもそれを回避できるように、なぜそれが起こっているのかを調べたいと思います。

特定の通知で一貫して切断されるわけではありません。特定のバイト転送サイズでは切断されません。すべてが散発的であるように見えます。単一の接続で送信できるデータ転送またはペイロード数に特定の制限はありますか?1つの接続を常に開いている人々のソリューションを見ると、それは問題ではないと思います。3回の通知後に接続が切断され、14回の通知後に接続が切断されました。14歳を過ぎたのを見たことがありません。

他の誰かがこのタイプの問題を経験しましたか?これはどのように処理できますか?

4

2 に答える 2

11

この問題は、無効なデバイストークンをAPNSサーバーに送信したことが原因で発生しました。この特定のケースでは、それは開発トークンでした。無効なデバイストークンがAPNSに送信されると、ソケットが切断されます。これはいくつかの頭痛の種を引き起こす可能性があり、Appleは将来のアップデートで対処する予定であるとして対処しています。

于 2010-03-09T21:38:56.643 に答える
2

私は少しの間同じ問題を抱えていて、それに取り組むために2つのことをしました:

  1. 自動再接続ロジックを配置します。接続をできるだけ長く維持しようとしますが、Appleは時々接続を切断します。これを処理する準備をしてください。
  2. 拡張インターフェースに移動します。単純なインターフェース(APNS gemや他の多くのユーザーが使用しているもの)を使用すると、エラーがフィードバックなしで切断をトリガーします。拡張フォーマットに切り替えると、何かが発生するたびに整数が返されます。不正なトークンは8が返される結果になります。これを使用して、データベースからデバイスを削除します。

EventMachineを使用した現在の接続コードは次のとおりです。

module Apns

  module SocketHandler
    def initialize(wrapper)
      @wrapper = wrapper
    end

    def post_init
      start_tls(:cert_chain_file => @wrapper.pem_path,
                :private_key_file => @wrapper.rsa_path,
                :verify_peer => false)
    end

    def receive_data(data)
      @wrapper.read_data!(data)
    end

    def unbind
      @wrapper.connection_closed!
    end

    def write(data)
      begin
        send_data(data)
      rescue => exc
        @wrapper.connection_error!(exc)
      end
    end

    def close!
      close_connection
    end
  end

  class Connection
    attr_reader :pem_path, :rsa_path

    def initialize(host, port, credentials_path, monitoring, read_data_handler)
      setup_credentials(credentials_path)
      @monitoring = monitoring
      @host = host
      @port = port
      @read_data_handler = read_data_handler
      open_connection!
    end

    def write(data)
      @connection.write(data)
    end

    def open?
      @status == :open
    end

    def connection_closed!
      @status = :closed
    end

    def connection_error!(exception)
      @monitoring.inform_exception!(exception, self)
      @status = :error
    end

    def close!
      @connection.close!
    end

    def read_data!(data)
      @read_data_handler.call(data)
    end

    private
    def setup_credentials(credentials_path)
      @pem_path = "#{credentials_path}.pem"
      @rsa_path = "#{credentials_path}.rsa"
      raise ArgumentError.new("#{credentials_path}.pem and #{credentials_path}.rsa must exist!") unless (File.exists?(@pem_path) and File.exists?(@rsa_path))
    end

    def open_connection!
      @connection = EventMachine.connect(@host, @port, SocketHandler, self)
      @status = :open
    end
  end
end

エンドエンド

通知のIDフィールドを使用して、接続の書き込みと読み取りを分離し、受信したフィードバックとともに送信する相関通知に関連付けます。

于 2011-12-18T12:40:58.303 に答える