I'm currently working on a server-side push notification service with Apple push notification. I'm working with boost asio. Here's my code :
void IPhonePush::connection() {
std::cout << "Push iPhone connection" << std::endl;
std::cout << getCertif() << std::endl;
m_context.set_options(boost::asio::ssl::context::default_workarounds
| boost::asio::ssl::context::no_sslv2
| boost::asio::ssl::context::single_dh_use);
m_context.set_password_callback(boost::bind(&IPhonePush::get_password, this));
m_context.use_certificate_chain_file(getCertif().c_str());
m_context.use_private_key_file(getKey().c_str(), boost::asio::ssl::context::pem);
boost::asio::ip::tcp::endpoint ep(boost::asio::ip::address::from_string(tools::Ip::getServiceIp("gateway.push.apple.com")), 2195);
m_socket.lowest_layer().async_connect(ep,
boost::bind(&IPhonePush::handle_connection,
this,
boost::asio::placeholders::error));
}
void IPhonePush::handle_connection(const boost::system::error_code& error) {
if (!error) {
std::cout << "/////////// Connected to PUSH SERVER !!!" << std::endl;
start_handshake();
} else {
std::cout << "/////////// Error Connecting to push: " << error.message() << std::endl;
}
}
void IPhonePush::start_handshake() {
m_socket.async_handshake(boost::asio::ssl::stream_base::client,
boost::bind(&IPhonePush::handle_handshake,
this,
boost::asio::placeholders::error));
}
The tools::Ip::getServiceIp gives me the ip resolved from the dns :
namespace tools {
class Ip {
public:
static std::string getServiceIp(std::string url) {
boost::asio::io_service io;
tcp::resolver resolver(io);
tcp::resolver::query query(url, "");
tcp::resolver::iterator iter = resolver.resolve(query);
tcp::endpoint ep;
while (iter != tcp::resolver::iterator()) {
ep = *iter++;
break;
}
return ep.address().to_string();
}
};
}
The thing is, the async_connect is called, and then nothing... handle_connection is never called not even with an error.
I'm currently wondering if the problem is not coming from resolving the dns into an ip to connect. If there another way to ask for a connection with an endpoint pointing towards gateway.push.apple.com directly (without resolving IP) ?
EDIT 1 :
int main() {
boost开发者_如何学运维::asio::io_service io_push;
push::IPhonePush ifpush(io_push);
ifpush.connection();
io_push.run();
}
I'm currently wondering if the problem is not coming from resolving the dns into an ip to connect.
I don't think this is the cause. Here is a sample program showing synchronous resolve and connect working just fine.
mac:stackoverflow samm$ cat push.cc
#include <boost/asio.hpp>
#include <iostream>
int
main( unsigned argc, const char** argv )
{
using namespace boost::asio;
io_service io_service;
ip::tcp::resolver resolver( io_service );
ip::tcp::resolver::query query(
"gateway.push.apple.com",
"2195"
);
ip::tcp::resolver::iterator i = resolver.resolve( query );
ip::tcp::socket socket( io_service );
socket.connect( *i );
std::cout << "connected to: " << ip::tcp::endpoint(*i) << std::endl;
}
mac:stackoverflow samm$ g++ -I /opt/local/include -L/opt/local/lib -lboost_system -Wl,-rpath,/opt/local/lib push.cc
mac:stackoverflow samm$ ./a.out
connected to: 17.172.239.6:2195
mac:stackoverflow samm$
In my experience, problems like this are typically caused the the io_service
running out of work or not running at all.
精彩评论