私は少しの間同じ問題を抱えていて、それに取り組むために2つのことをしました:
- 自動再接続ロジックを配置します。接続をできるだけ長く維持しようとしますが、Appleは時々接続を切断します。これを処理する準備をしてください。
- 拡張インターフェースに移動します。単純なインターフェース(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フィールドを使用して、接続の書き込みと読み取りを分離し、受信したフィードバックとともに送信する相関通知に関連付けます。