我有一段时间遇到同样的问题,并做了两件事来解决它:
- 设置一些自动重新连接逻辑:我尝试尽可能长时间地保持连接,但 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 字段与我发送的相关通知以及我收到的反馈。