Приветствую
Подскажите где у меня косяк, а смотрю в документацию - вижу фигу
Вызов Send(), чернового варианта класса описанного ниже, выполняется только один раз, в чем косяк у меня, а то смотрю в документацию - вижу фигу.
class CPush
{
private:
boost::asio::io_service io_service;
boost::asio::ip::tcp::resolver::iterator iterator;
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> * psocket;
boost::asio::streambuf response;
bool verify_certificate(bool preverified, boost::asio::ssl::verify_context & ctx)
{
char subject_name[256];
X509 * cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
std::cout << "Verifying " << subject_name << std::endl;
return preverified;
}
void handle_connect(const boost::system::error_code & error)
{
if (error)
std::cerr << "Connect failed: " << error.message() << std::endl;
else
{
psocket->async_handshake(boost::asio::ssl::stream_base::client,
boost::bind(&CPush::handle_handshake,
this,
boost::asio::placeholders::error));
std::cout << "Connection OK!" << std::endl;
}
}
void handle_handshake(const boost::system::error_code & error)
{
if (error)
std::cerr << "Handshake failed: " << error.message() << std::endl;
else
{
std::string json("{\"registration_ids\":[\"" + token + "\"],"
+"\"notification\":null,"
.......
+"\"priority\":\"high\","
+"\"time_to_live\":15}");
std::stringstream request;
request << "POST " << GOOGLE_API << " HTTP/1.1\r\n"
<< "Host: " << GOOGLE_HOST << "\r\n" // << ":" << GOOGLE_PORT
<< "Content-Type: application/json; charset=utf-8\r\n"
<< "Content-Length: " << json.size() << "\r\n"
<< "Authorization: key=" << push_key << "\r\n"
<< "Connection: close\r\n"
<< "\r\n"
<< json << "\r\n\r\n";
std::cout << "Sending request...\n" << request.str();
boost::asio::async_write(*psocket,
boost::asio::buffer(request.str()),
boost::bind(&CPush::handle_write,
this,
boost::asio::placeholders::error));
}
}
void handle_write(const boost::system::error_code & error)
{
if (error)
std::cerr << "Write failed: " << error.message() << std::endl;
else
{
boost::asio::async_read_until(*psocket,
response, "\r\n",
boost::bind(&CPush::handle_read_status,
this,
boost::asio::placeholders::error));
std::cout << "Sending request OK!" << std::endl;
}
}
void handle_read_status(const boost::system::error_code & error)
{
if (error)
std::cout << "Error read status: " << error.message() << std::endl;
else
{
// Check that response is OK.
std::istream response_stream(&response);
std::string http_version;
response_stream >> http_version;
unsigned int status_code;
response_stream >> status_code;
std::string status_message;
std::getline(response_stream, status_message);
if (!response_stream || http_version.substr(0, 5) != "HTTP/")
{
std::cout << "Invalid response\n";
return;
}
if (status_code != 200)
{
std::cout << "Response returned with status code ";
std::cout << status_code << "\n";
// return;
}
// Read the response headers, which are terminated by a blank line.
boost::asio::async_read_until(*psocket,
response, "\r\n\r\n",
boost::bind(&CPush::handle_read_header,
this,
boost::asio::placeholders::error));
}
}
void handle_read_header(const boost::system::error_code & error)
{
if (error)
std::cout << "Error read header: " << error.message() << std::endl;
else
{
// Process the response headers.
std::istream response_stream(&response);
std::string header;
while (std::getline(response_stream, header) && header != "\r")
std::cout << header << "\n";
std::cout << "\n";
// Write whatever content we already have to output.
if (response.size() > 0)
std::cout << &response;
// Start reading remaining data until EOF.
boost::asio::async_read(*psocket,
response,
boost::asio::transfer_at_least(1),
boost::bind(&CPush::handle_read_content,
this,
boost::asio::placeholders::error));
}
}
void handle_read_content(const boost::system::error_code & error)
{
if (error)
{
if (error != boost::asio::error::eof)
std::cout << "Error read content: " << error.message() << std::endl;
}
else
{
// Write all of the data that has been read so far.
std::cout << &response;
// Continue reading remaining data until EOF.
boost::asio::async_read(*psocket,
response,
boost::asio::transfer_at_least(1),
boost::bind(&CPush::handle_read_content,
this,
boost::asio::placeholders::error));
}
}
public:
CPush(void)
{
boost::asio::ip::tcp::resolver resolver(io_service);
boost::asio::ip::tcp::resolver::query query(GOOGLE_HOST, GOOGLE_PORT);
iterator = resolver.resolve(query);
boost::asio::ssl::context context(boost::asio::ssl::context::sslv23);
context.set_default_verify_paths();
psocket = new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(io_service, context);
psocket->set_verify_mode(boost::asio::ssl::context::verify_none);
psocket->set_verify_callback(boost::bind(&CPush::verify_certificate, this, _1, _2));
}
void Send(void)
{
boost::asio::async_connect(psocket->lowest_layer(),
iterator,
boost::bind(&CPush::handle_connect,
this,
boost::asio::placeholders::error));
io_service.run();
}
};