什么会导致与 APNS 的连接间歇性断开?

发布于 2024-08-23 12:59:27 字数 331 浏览 9 评论 0原文

我有一个 ruby​​ 脚本,可以打开与 Apple 推送服务器的连接并发送所有待处理的通知。我看不出任何原因,但当 Apple 断开我的脚本时,我收到了损坏的管道错误。我已经编写了脚本来适应这种情况的发生,但我宁愿找出它发生的原因,这样我就可以首先避免它。

它不会始终在收到特定通知时断开连接。它不会在特定字节传输大小时断开连接。一切似乎都是零星的。在单个连接上可以发送的数据传输或有效负载数量是否有某些限制?看到人们的解决方案始终保持一个连接打开,我认为这不是问题。我看到连接在 3 个通知后断开,我也看到连接在 14 个通知后断开。我从来没有见过它超过 14。

有其他人遇到过这种类型的问题吗?这该如何处理呢?

I've got a ruby script that opens a connection to Apple's push server and sends all the pending notifications. I can't see any reason why, but I get broken pipe errors when Apple disconnects my script. I've written my script to accomodate this happening, but I would rather just find out why it's happening so I can avoid it in the first place.

It doesn't consistently disconnect on a specific notification. It doesn't disconnect at a certain byte transfer size. Everything appears to be sporadic. Are there certain limitations to the data transfer or payload count you can send on a single connection? Seeing people's solutions that hold one connection open all the time, I would assume that isn't the issue. I've seen the connection drop after 3 notifications, and I've seen it drop after 14 notifications. I've never seen it make it past 14.

Has anyone else experienced this type of problem? How can this be handled?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

淡淡の花香 2024-08-30 12:59:27

该问题是由于向 APNS 服务器发送无效的设备令牌引起的。在这个具体案例中,它是一个开发代币。当无效的设备令牌发送到 APNS 时,它会断开套接字。这可能会引起一些麻烦,Apple 已将其解决为他们将在未来的更新中解决的问题。

The problem was caused by sending an invalid device token to the APNS server. In this specific case it was a development token. When an invalid device token is sent to APNS, it disconnects the socket. This can cause some headaches, and has been addressed by Apple as being something they are going to address in future updates.

够钟 2024-08-30 12:59:27

我也遇到过同样的问题,做了两件事来解决它:

  1. 放置一些自动重新连接逻辑:我尝试尽可能长时间地保持连接,但苹果会时不时地断开连接。准备好处理这个问题。
  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

end
它使用通知中的 ID 字段将

连接中的写入和读取分开,以将我发送的通知与收到的反馈相关联。

I had the same issue for a bit and did two things to tackle it:

  1. Put some auto-reconnect logic in place: I try to keep my connection for as long as possible but Apple will disconnect you every now and then. Be prepared to handle this.
  2. Move to the enhanced interface: Using the simple interface (that's what the APNS gem and many others use) errors will trigger disconnection without any feedback. If you switch to the enhanced format you will receive an integer back every time something happens. Bad tokens will result in a 8 being returned, and I use this to remove the device from my database.

Here's my current connection code, using 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

end
end

It separates writes and reads in the connection, using the ID field in the notification to correlated notifications I send with feedback I receive.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文