2010-03-03 6 views
5

Tôi đã có một tập lệnh ruby ​​mở một kết nối với máy chủ đẩy của Apple và gửi tất cả các thông báo đang chờ xử lý. Tôi không thể thấy bất kỳ lý do gì, nhưng tôi bị lỗi đường ống bị hỏng khi Apple ngắt kết nối tập lệnh của tôi. Tôi đã viết kịch bản của tôi để đáp ứng điều này xảy ra, nhưng tôi chỉ muốn tìm hiểu lý do tại sao nó xảy ra vì vậy tôi có thể tránh nó ở nơi đầu tiên.Điều gì có thể gây ra kết nối với APNS để ngắt kết nối liên tục?

Nó không liên tục ngắt kết nối trên một thông báo cụ thể. Nó không ngắt kết nối ở một kích thước chuyển byte nào đó. Mọi thứ dường như rời rạc. Có giới hạn nhất định nào đối với việc chuyển dữ liệu hoặc số lượng tải trọng bạn có thể gửi trên một kết nối không? Nhìn thấy các giải pháp của mọi người giữ một kết nối mở tất cả các thời gian, tôi sẽ cho rằng đó không phải là vấn đề. Tôi đã nhìn thấy kết nối thả sau 3 thông báo, và tôi đã nhìn thấy nó thả sau 14 thông báo. Tôi chưa bao giờ thấy nó vượt qua 14.

Có ai khác trải qua loại sự cố này không? Làm thế nào điều này có thể được xử lý?

Trả lời

11

Sự cố xảy ra do gửi mã thông báo thiết bị không hợp lệ đến máy chủ APNS. Trong trường hợp cụ thể này, đó là một mã thông báo phát triển. Khi mã thông báo thiết bị không hợp lệ được gửi đến APNS, nó sẽ ngắt kết nối ổ cắm. Điều này có thể gây ra một số nhức đầu, và đã được giải quyết bởi Apple như là một cái gì đó họ sẽ giải quyết trong bản cập nhật trong tương lai.

+0

Bạn thấy họ sẽ giải quyết ở đâu? Và bạn đã làm gì để giải quyết vấn đề? Chỉ cần đóng và mở lại ổ cắm? – Sam

2

tôi đã cùng một vấn đề cho một chút và đã làm hai điều để giải quyết nó:

  1. Đặt một số logic tự động kết nối lại tại chỗ: Tôi cố gắng giữ cho kết nối của tôi cho càng lâu càng tốt nhưng Apple sẽ ngắt kết nối bạn tất cả bây giờ và sau đó. Hãy chuẩn bị để xử lý việc này.
  2. Chuyển sang giao diện nâng cao: Sử dụng giao diện đơn giản (đó là những gì APNS đá quý và nhiều người khác sử dụng) sẽ kích hoạt ngắt kết nối mà không có bất kỳ phản hồi nào. Nếu bạn chuyển sang số enhanced format, bạn sẽ nhận được một số nguyên sau mỗi lần xảy ra sự cố. Mã thông báo lỗi sẽ dẫn đến 8 mã bị trả về và tôi sử dụng mã này để xóa thiết bị khỏi cơ sở dữ liệu của tôi.

Dưới đây là mã kết nối hiện tại của tôi, sử dụng 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 

cuối cuối

Nó tách viết và đọc trong kết nối, sử dụng trường ID trong thông báo để thông báo tương quan tôi gửi với phản hồi tôi nhận được.