2017-03-16 2 views
1

J'utilise nghttp2_asio pour me connecter au service de développement Apple Push Notifications. J'essaie de suivre le APN guide as written:nghttp2 asio se connecter à la notification Apple Push expire

Gardez vos connexions avec les APN ouverts à travers plusieurs notifications; faire pas ouvrir et fermer les connexions de manière répétée. Les APN traitent la connexion et la déconnexion rapides comme une attaque de déni de service. Vous devez laisser un connexion ouverte à moins que vous savez qu'il sera inactif pendant une période prolongée

Je suis en train de l'écrire d'une manière que la connexion ne chronométrer pas. Cependant, ma connexion expire après environ une minute. Je vois l'envoi d'un cadre PING pour non nghttp2_asio mais pas pour la version asio qu'Apple dit aussi:

Vous pouvez vérifier la santé de votre connexion à l'aide d'un HTTP/2 PING cadre .

Comment puis-je rester connecté à APN?

code

#include <nghttp2/asio_http2_client.h> 

#include <boost/asio/io_service.hpp> 
#include <boost/asio/ssl/context.hpp> 

#include <boost/uuid/uuid.hpp> 
#include <boost/uuid/uuid_generators.hpp> 
#include <boost/uuid/uuid_io.hpp> 

#include <iostream> 

#define LOG_EASY(STREAM) std::cout << __PRETTY_FUNCTION__ << ": " << STREAM << std::endl; 

int main(int argc, char *argv[]) 
{ 
    boost::asio::io_service io_service; 
    boost::asio::ssl::context ssl_context(boost::asio::ssl::context::sslv23); 

    std::string hostname("https://api.development.push.apple.com:443"); 

    // The context options 
    ssl_context.set_options(boost::asio::ssl::context::default_workarounds | 
      boost::asio::ssl::context::no_sslv2 | 
      boost::asio::ssl::context::single_dh_use); 

    // Now put it up 
    ssl_context.use_private_key_file("/home/mike/dev/cpp/sw/run/certs/apn.key", boost::asio::ssl::context::pem); 
    ssl_context.use_certificate_file("/home/mike/dev/cpp/sw/run/certs/apn.crt", boost::asio::ssl::context::pem); 

    boost::system::error_code ec; 
    nghttp2::asio_http2::client::configure_tls_context(ec, ssl_context); 
    boost::asio::detail::throw_error(ec); // Throw as necessary 

    // Make the new session 
    nghttp2::asio_http2::client::session session(io_service, 
      ssl_context, 
      "api.development.push.apple.com", 
      "443"); 

    // On connect callberk 
    session.on_connect([ &session, &hostname ](boost::asio::ip::tcp::resolver::iterator endpoint) { 
     LOG_EASY("Connected!"); 

     // Error cheek 
     boost::system::error_code e; 

     // Generate a crazy filename 
     boost::uuids::uuid uuid = boost::uuids::random_generator()(); 

     // Header merp 
     nghttp2::asio_http2::header_map headers; 
     headers.emplace("apns-id", (nghttp2::asio_http2::header_value){ boost::uuids::to_string(uuid), false }); 
     headers.emplace("apns-expiration", (nghttp2::asio_http2::header_value){ "0", false }); 
     headers.emplace("apns-priority", (nghttp2::asio_http2::header_value){ "10", false }); 
     headers.emplace("apns-topic", (nghttp2::asio_http2::header_value){ "com.company.App-Topic", false }); 

     // Send a test push 
     const nghttp2::asio_http2::client::request *request = session.submit(e, 
        "POST", 
        hostname+"/3/device/129a46cbac12d8c523aaf8a1758d07f0fc8b291c776aed4a7dc6f1535be1521e", 
        "{ \"aps\" : { \"alert\" : \"Hello\" } }", 
        headers); 

     boost::asio::detail::throw_error(e); // Throw as necessary 

     // Now hook 
     request->on_response([](const nghttp2::asio_http2::client::response &response){ 
      LOG_EASY("response received! Status code: " << response.status_code()); 

      response.on_data([](const uint8_t *data, std::size_t len) { 
       LOG_EASY("Response length: " << len); 
       LOG_EASY(std::string((const char *)data, len)); 
      }); 
     }); 

     // On push 
     request->on_push([](const nghttp2::asio_http2::client::request &push){ 
      LOG_EASY("push request received!"); 

      push.on_response([](const nghttp2::asio_http2::client::response &res){ 
       LOG_EASY("push response received!"); 

       res.on_data([](const uint8_t *data, std::size_t len) { 
        LOG_EASY(std::string((const char *)data, len)); 
       }); 
      }); 

     }); 

     // On close 
     request->on_close([](uint32_t error_code){ 
      LOG_EASY("Request close: " << error_code); 
     }); 
    }); 

    // On error kerlbook 
    session.on_error([](const boost::system::error_code &error) { 
     LOG_EASY(error.message()); 
    }); 

    // Run the servace 
    io_service.run(); 
} 

Sortie

main(int, char**)::<lambda(boost::asio::ip::basic_resolver<boost::asio::ip::tcp>::iterator)>: Connected! 
main(int, char**)::<lambda(boost::asio::ip::basic_resolver<boost::asio::ip::tcp>::iterator)>::<lambda(const nghttp2::asio_http2::client::response&)>: response received! Status code: 200 
main(int, char**)::<lambda(boost::asio::ip::basic_resolver<boost::asio::ip::tcp>::iterator)>::<lambda(const nghttp2::asio_http2::client::response&)>::<lambda(const uint8_t*, std::size_t)>: Response length: 0 
main(int, char**)::<lambda(boost::asio::ip::basic_resolver<boost::asio::ip::tcp>::iterator)>::<lambda(const nghttp2::asio_http2::client::response&)>::<lambda(const uint8_t*, std::size_t)>: 
main(int, char**)::<lambda(boost::asio::ip::basic_resolver<boost::asio::ip::tcp>::iterator)>::<lambda(uint32_t)>: Request close: 0 
main(int, char**)::<lambda(const boost::system::error_code&)>: Connection timed out 

Répondre