#include "curl/curl.h"
#define APNS_URL "https://gateway.push.apple.com:2195"
int wait_on_socket(int sockfd, int for_recv, long timeout_ms)
{
struct timeval tv;
fd_set infd, outfd, errfd;
int res;
tv.tv_sec = timeout_ms / 1000;
tv.tv_usec= (timeout_ms % 1000) * 1000;
FD_ZERO(&infd);
FD_ZERO(&outfd);
FD_ZERO(&errfd);
FD_SET(sockfd, &errfd); /* always check for error */
if(for_recv)
{
FD_SET(sockfd, &infd);
}
else
{
FD_SET(sockfd, &outfd);
}
/* select() returns the number of signalled sockets or -1 */
res = select(sockfd + 1, &infd, &outfd, &errfd, &tv);
return res;
}
void token2bytes(const char *token, char *bytes)
{
int val;
while (*token) {
sscanf(token, "%2x", &val);
*(bytes++) = (char)val;
token += 2;
while (*token == ' ') { // skip space
++token;
}
}
}
unsigned long packMessage(char *message, const unsigned char command, const char *tokenBytes, const char *payload)
{
unsigned long payloadLength = strlen(payload);
unsigned short networkTokenLength = htons(32);
unsigned short networkPayloadLength = htons(payloadLength);
memcpy(message, &command, sizeof(unsigned char));
message += sizeof(unsigned char);
memcpy(message, &networkTokenLength, sizeof(unsigned short));
message += sizeof(unsigned short);
memcpy(message, tokenBytes, 32);
message += 32;
memcpy(message, &networkPayloadLength, sizeof(unsigned short));
message += sizeof(unsigned short);
memcpy(message, payload, payloadLength);
return payloadLength + 37;
}
uint32_t Reconnect()
{
KEY_LOG("START Reconnect");
CURLcode ret;
curl_global_init(CURL_GLOBAL_DEFAULT);
CRemindAo::hnd = curl_easy_init();
if(! CRemindAo::hnd)
{
curl_global_cleanup();
ERR_LOG("Reconnect::Curl_easy_init ERROR");
return DO_REAL_APP_TASK_INIT_ERR;
}
curl_easy_setopt(CRemindAo::hnd, CURLOPT_URL, APNS_URL);
curl_easy_setopt(CRemindAo::hnd, CURLOPT_PROXY, CRemindAo::ms_strAppProxyConfig.c_str());
curl_easy_setopt(CRemindAo::hnd, CURLOPT_CONNECT_ONLY, 1L);
curl_easy_setopt(CRemindAo::hnd, CURLOPT_NOPROGRESS, 1L);
curl_easy_setopt(CRemindAo::hnd, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(CRemindAo::hnd, CURLOPT_CONNECTTIMEOUT, 6);
curl_easy_setopt(CRemindAo::hnd, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(CRemindAo::hnd, CURLOPT_SSLCERTTYPE,"PEM");
curl_easy_setopt(CRemindAo::hnd, CURLOPT_SSLKEYTYPE, "PEM");
curl_easy_setopt(CRemindAo::hnd, CURLOPT_SSLCERT,CRemindAo::ms_strPemDir.c_str());
curl_easy_setopt(CRemindAo::hnd, CURLOPT_SSLKEY,CRemindAo::ms_strPemDir.c_str());
curl_easy_setopt(CRemindAo::hnd, CURLOPT_KEYPASSWD, m_oRemindTaskDo.GetVerifyCode().c_str());
ret = curl_easy_perform(CRemindAo::hnd);
if(CURLE_OK != ret)
{
curl_easy_cleanup(CRemindAo::hnd);
curl_global_cleanup();
CRemindAo::hnd = NULL;
ERR_LOG("Curl_easy_perform ERROR errmsg:[%s]", strerror(ret));
return DO_REAL_APP_TASK_CURL_ERR;
}
KEY_LOG("END Reconnect");
return 0;
}
int SendRemind(string strIn)
{
int dwRet = 0;
DEBUG_LOG("%s Start uin=[%s]",__FUNCTION__,strIn.c_str());
CURLcode ret;
int sockfd; /* socket */
long sockextr;
size_t iolen;
if(CRemindAo::hnd == NULL)
{
dwRet = Reconnect();
if(dwRet !=0)
{
ERR_LOG("DoAppRemindTask::Reconnect Error! dwRet[%u], device[%s]", dwRet,m_strDeviceToken.c_str());
return dwRet;
}
}
ret = curl_easy_getinfo(CRemindAo::hnd, CURLINFO_LASTSOCKET, &sockextr);
if(CURLE_OK != ret || sockextr<=0)
{
curl_easy_cleanup(CRemindAo::hnd);
curl_global_cleanup();
CRemindAo::hnd = NULL;
dwRet = Reconnect();
if(dwRet !=0)
{
ERR_LOG("DoAppRemindTask::curl_easy_getinfo Error! dwRet[%u], device[%s]", dwRet,m_strDeviceToken.c_str());
return dwRet;
}
ret = curl_easy_getinfo(CRemindAo::hnd, CURLINFO_LASTSOCKET, &sockextr);
if(CURLE_OK != ret)
{
usleep(50*1000);
ERR_LOG("Curl_easy_perform ERROR errmsg:[%s], device:[%s], sendMsg:[%s]", strerror(ret),m_strDeviceToken.c_str(),m_strMsgJson.c_str());
dwRet = DO_REAL_APP_TASK_CURL_ERR;
}
}
sockfd = sockextr;
if(!wait_on_socket(sockfd, 0, 6000L))
{
ERR_LOG("Error: SOCKET TIME OUT device:[%s], sendMsg:[%s]",m_strDeviceToken.c_str(),m_strMsgJson.c_str());
dwRet = DO_REAL_APP_TASK_CURL_ERR;
}
else
{
char tokenBytes[32];
char message[293];
unsigned long msgLength;
token2bytes(m_strDeviceToken.c_str(), tokenBytes);
msgLength = packMessage(message, 0, tokenBytes, m_strMsgJson.c_str());
ret = curl_easy_send(CRemindAo::hnd, message, msgLength, &iolen);
if(CURLE_OK != ret)
{
ERR_LOG("Curl_easy_send ERROR errmsg:[%s], device:[%s], sendMsg:[%s]", curl_easy_strerror(ret),m_strDeviceToken.c_str(),m_strMsgJson.c_str());
dwRet = DO_REAL_APP_TASK_CURL_ERR;
}
else
{
DEBUG_LOG("send app msg success! device:[%s], sendMsg:[%s]",m_strDeviceToken.c_str(),m_strMsgJson.c_str());
}
}
return dwRet;
}
curl实现apns
最新推荐文章于 2019-07-31 11:21:31 发布