HttpClient是HTTP的客户端的接口。封装了各种对象,处理cookies,身份认证,连接管理等。
HttpClient的使用一般包括下面6个步骤:
(1)创建HttpClient实例;
(2)设置某种链接方法的类型(GET、POST),通过setUrl传入待连接的地址;
(3)设置响应回调函数,读取response;
(4)添加请求到HttpClient任务队列;
(5)释放连接;
(6)对得到的内容进行处理。
代码实例如下
void AsyncHttp::doHttpRequestInternal(HttpRequestData* pRequest)
{
//cocos2d::network::HttpClient::getInstance()->setTimeoutForConnect(1);
if (pRequest == nullptr)
return;
m_threadLocker.lock();
unsigned int nCurTagID = m_nNextRequestID;
m_nNextRequestID++;
m_threadLocker.unlock();
char szTag[100] = { '\0' };
sprintf(szTag, "%d", nCurTagID);
cocos2d::network::HttpRequest* request = new cocos2d::network::HttpRequest();//创建request实例
request->setUrl(pRequest->url.c_str());//传入待连接的地址
request->setRequestType(pRequest->requestType);//设置连接类型
//这是回调对象和回调函数,无论服务器返回怎样的状态,响应主体response body总是可读的,这至关重要
request->setResponseCallback(this, httpresponse_selector(AsyncHttp::onHttpRequestCompletedInternal));
request->setTag(szTag);
request->setHeaders(pRequest->headers);
//请求的数据
if (pRequest->requestData.msgData != nullptr)
{
request->setRequestData(pRequest->requestData.msgData, pRequest->requestData.dataLen);
}
if (pRequest->subscriber)
{
m_threadLocker.lock();
m_RequestList.insert(std::make_pair(nCurTagID, pRequest));
m_threadLocker.unlock();
}
cocos2d::network::HttpClient::getInstance()->send(request);//添加请求到HttpClient任务队列
//释放内存
request->release();//释放连接,这是一个可以让整个流程变得完整的关键步骤, 我们必须告诉HttpClient,我们已经完成了连接,并且它现在可以重用。如果不这样做的话,HttpClient将无限期地等待一个连接释放,以便它可以重用。
}
//回调函数
void AsyncHttp::onHttpRequestCompletedInternal(cocos2d::network::HttpClient *pSender, cocos2d::network::HttpResponse *pResponse)
{
if (pResponse == nullptr)
return;
if (pResponse->getHttpRequest()->getTag() == nullptr || strlen(pResponse->getHttpRequest()->getTag()) == 0)
return;
unsigned int nTagID = 0;
sscanf(pResponse->getHttpRequest()->getTag(), "%d", &nTagID);
if (nTagID == 0)
return;
if (!pResponse->isSucceed())
{
m_threadLocker.lock();
std::map<int, HttpRequestData*>::iterator requestIt = m_RequestList.find(nTagID);
if (requestIt != m_RequestList.end())
{
m_RequestList.erase(requestIt);
}
m_threadLocker.unlock();
}
else
{
m_threadLocker.lock();
std::map<int, HttpRequestData*>::iterator requestIt = m_RequestList.find(nTagID);
if (requestIt != m_RequestList.end())
{
HttpRequestData* pRequestData = requestIt->second;
pRequestData->requestData.setMessageData(pResponse);
HttpRequestData* pData = requestIt->second;
m_ReceiveBuffer.PushData(pData);
m_RequestList.erase(requestIt);
}
m_threadLocker.unlock();
}
}