curl实现apns

#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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值