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