是什么导致APNS连接断断续续?

时间:2010-03-03 00:04:55

标签: ruby-on-rails ruby sockets apple-push-notifications

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

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

还有其他人遇到过这类问题吗?怎么办呢?

2 个答案:

答案 0 :(得分:11)

问题是由向APNS服务器发送无效设备令牌引起的。在这种特定情况下,它是一个开发令牌。当向APNS发送无效设备令牌时,它会断开套接字。这可能会引起一些麻烦,Apple已经解决了这些问题,他们将在未来的更新中解决这些问题。

答案 1 :(得分:2)

我有一点同样的问题并做了两件事来解决它:

  1. 放置一些自动重新连接逻辑:我尽可能长时间地保持连接,但Apple会不时地断开你的连接。准备好处理这个问题。
  2. 转到增强型界面:使用简单界面(这是APNS gem和许多其他人使用的)错误将触发断开而没有任何反馈。如果切换到enhanced format,每次发生事件时都会收到一个整数。错误的令牌将导致返回8,我使用它来从我的数据库中删除该设备。
  3. 这是我当前的连接代码,使用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字段发送我发送的相关通知和我收到的反馈。