Merge pull request #6948 from lite3/v3

Add immediate send request
This commit is contained in:
minggo 2014-06-26 16:05:58 +08:00
commit e0e9d3379c
4 changed files with 292 additions and 135 deletions

View File

@ -47,8 +47,8 @@ namespace network {
static std::mutex s_requestQueueMutex; static std::mutex s_requestQueueMutex;
static std::mutex s_responseQueueMutex; static std::mutex s_responseQueueMutex;
static std::mutex s_SleepMutex; static std::mutex s_SleepMutex;
static std::condition_variable s_SleepCondition; static std::condition_variable s_SleepCondition;
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
@ -95,12 +95,12 @@ static size_t writeHeaderData(void *ptr, size_t size, size_t nmemb, void *stream
} }
static int processGetTask(HttpRequest *request, write_callback callback, void *stream, long *errorCode, write_callback headerCallback, void *headerStream); static int processGetTask(HttpRequest *request, write_callback callback, void *stream, long *errorCode, write_callback headerCallback, void *headerStream, char *errorBuffer);
static int processPostTask(HttpRequest *request, write_callback callback, void *stream, long *errorCode, write_callback headerCallback, void *headerStream); static int processPostTask(HttpRequest *request, write_callback callback, void *stream, long *errorCode, write_callback headerCallback, void *headerStream, char *errorBuffer);
static int processPutTask(HttpRequest *request, write_callback callback, void *stream, long *errorCode, write_callback headerCallback, void *headerStream); static int processPutTask(HttpRequest *request, write_callback callback, void *stream, long *errorCode, write_callback headerCallback, void *headerStream, char *errorBuffer);
static int processDeleteTask(HttpRequest *request, write_callback callback, void *stream, long *errorCode, write_callback headerCallback, void *headerStream); static int processDeleteTask(HttpRequest *request, write_callback callback, void *stream, long *errorCode, write_callback headerCallback, void *headerStream, char *errorBuffer);
// int processDownloadTask(HttpRequest *task, write_callback callback, void *stream, int32_t *errorCode); // int processDownloadTask(HttpRequest *task, write_callback callback, void *stream, int32_t *errorCode);
static void processResponse(HttpResponse* response, char* errorBuffer);
// Worker thread // Worker thread
void HttpClient::networkThread() void HttpClient::networkThread()
@ -144,71 +144,9 @@ void HttpClient::networkThread()
// Create a HttpResponse object, the default setting is http access failed // Create a HttpResponse object, the default setting is http access failed
HttpResponse *response = new HttpResponse(request); HttpResponse *response = new HttpResponse(request);
// request's refcount = 2 here, it's retained by HttpRespose constructor processResponse(response, s_errorBuffer);
request->release();
// ok, refcount = 1 now, only HttpResponse hold it.
long responseCode = -1;
int retValue = 0;
// Process the request -> get response packet
switch (request->getRequestType())
{
case HttpRequest::Type::GET: // HTTP GET
retValue = processGetTask(request,
writeData,
response->getResponseData(),
&responseCode,
writeHeaderData,
response->getResponseHeader());
break;
case HttpRequest::Type::POST: // HTTP POST
retValue = processPostTask(request,
writeData,
response->getResponseData(),
&responseCode,
writeHeaderData,
response->getResponseHeader());
break;
case HttpRequest::Type::PUT:
retValue = processPutTask(request,
writeData,
response->getResponseData(),
&responseCode,
writeHeaderData,
response->getResponseHeader());
break;
case HttpRequest::Type::DELETE:
retValue = processDeleteTask(request,
writeData,
response->getResponseData(),
&responseCode,
writeHeaderData,
response->getResponseHeader());
break;
default:
CCASSERT(true, "CCHttpClient: unkown request type, only GET and POSt are supported");
break;
}
// write data to HttpResponse
response->setResponseCode(responseCode);
if (retValue != 0)
{
response->setSucceed(false);
response->setErrorBuffer(s_errorBuffer);
}
else
{
response->setSucceed(true);
}
// add response packet into queue // add response packet into queue
s_responseQueueMutex.lock(); s_responseQueueMutex.lock();
s_responseQueue->pushBack(response); s_responseQueue->pushBack(response);
@ -234,15 +172,43 @@ void HttpClient::networkThread()
} }
// Worker thread
void HttpClient::networkThreadAlone(HttpRequest* request)
{
// Create a HttpResponse object, the default setting is http access failed
HttpResponse *response = new HttpResponse(request);
char errorBuffer[CURL_ERROR_SIZE] = { 0 };
processResponse(response, errorBuffer);
auto scheduler = Director::getInstance()->getScheduler();
scheduler->performFunctionInCocosThread([response, request]{
const ccHttpRequestCallback& callback = request->getCallback();
Ref* pTarget = request->getTarget();
SEL_HttpResponse pSelector = request->getSelector();
if (callback != nullptr)
{
callback(s_pHttpClient, response);
}
else if (pTarget && pSelector)
{
(pTarget->*pSelector)(s_pHttpClient, response);
}
response->release();
// do not release in other thread
request->release();
});
}
//Configure curl's timeout property //Configure curl's timeout property
static bool configureCURL(CURL *handle) static bool configureCURL(CURL *handle, char *errorBuffer)
{ {
if (!handle) { if (!handle) {
return false; return false;
} }
int32_t code; int32_t code;
code = curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, s_errorBuffer); code = curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, errorBuffer);
if (code != CURLE_OK) { if (code != CURLE_OK) {
return false; return false;
} }
@ -298,15 +264,15 @@ public:
* @param callback Response write callback * @param callback Response write callback
* @param stream Response write stream * @param stream Response write stream
*/ */
bool init(HttpRequest *request, write_callback callback, void *stream, write_callback headerCallback, void *headerStream) bool init(HttpRequest *request, write_callback callback, void *stream, write_callback headerCallback, void *headerStream, char *errorBuffer)
{ {
if (!_curl) if (!_curl)
return false; return false;
if (!configureCURL(_curl)) if (!configureCURL(_curl, errorBuffer))
return false; return false;
/* get custom header data (if set) */ /* get custom header data (if set) */
std::vector<std::string> headers=request->getHeaders(); std::vector<std::string> headers=request->getHeaders();
if(!headers.empty()) if(!headers.empty())
{ {
/* append custom headers one by one */ /* append custom headers one by one */
@ -350,20 +316,20 @@ public:
}; };
//Process Get Request //Process Get Request
static int processGetTask(HttpRequest *request, write_callback callback, void *stream, long *responseCode, write_callback headerCallback, void *headerStream) static int processGetTask(HttpRequest *request, write_callback callback, void *stream, long *responseCode, write_callback headerCallback, void *headerStream, char *errorBuffer)
{ {
CURLRaii curl; CURLRaii curl;
bool ok = curl.init(request, callback, stream, headerCallback, headerStream) bool ok = curl.init(request, callback, stream, headerCallback, headerStream, errorBuffer)
&& curl.setOption(CURLOPT_FOLLOWLOCATION, true) && curl.setOption(CURLOPT_FOLLOWLOCATION, true)
&& curl.perform(responseCode); && curl.perform(responseCode);
return ok ? 0 : 1; return ok ? 0 : 1;
} }
//Process POST Request //Process POST Request
static int processPostTask(HttpRequest *request, write_callback callback, void *stream, long *responseCode, write_callback headerCallback, void *headerStream) static int processPostTask(HttpRequest *request, write_callback callback, void *stream, long *responseCode, write_callback headerCallback, void *headerStream, char *errorBuffer)
{ {
CURLRaii curl; CURLRaii curl;
bool ok = curl.init(request, callback, stream, headerCallback, headerStream) bool ok = curl.init(request, callback, stream, headerCallback, headerStream, errorBuffer)
&& curl.setOption(CURLOPT_POST, 1) && curl.setOption(CURLOPT_POST, 1)
&& curl.setOption(CURLOPT_POSTFIELDS, request->getRequestData()) && curl.setOption(CURLOPT_POSTFIELDS, request->getRequestData())
&& curl.setOption(CURLOPT_POSTFIELDSIZE, request->getRequestDataSize()) && curl.setOption(CURLOPT_POSTFIELDSIZE, request->getRequestDataSize())
@ -372,10 +338,10 @@ static int processPostTask(HttpRequest *request, write_callback callback, void *
} }
//Process PUT Request //Process PUT Request
static int processPutTask(HttpRequest *request, write_callback callback, void *stream, long *responseCode, write_callback headerCallback, void *headerStream) static int processPutTask(HttpRequest *request, write_callback callback, void *stream, long *responseCode, write_callback headerCallback, void *headerStream, char *errorBuffer)
{ {
CURLRaii curl; CURLRaii curl;
bool ok = curl.init(request, callback, stream, headerCallback, headerStream) bool ok = curl.init(request, callback, stream, headerCallback, headerStream, errorBuffer)
&& curl.setOption(CURLOPT_CUSTOMREQUEST, "PUT") && curl.setOption(CURLOPT_CUSTOMREQUEST, "PUT")
&& curl.setOption(CURLOPT_POSTFIELDS, request->getRequestData()) && curl.setOption(CURLOPT_POSTFIELDS, request->getRequestData())
&& curl.setOption(CURLOPT_POSTFIELDSIZE, request->getRequestDataSize()) && curl.setOption(CURLOPT_POSTFIELDSIZE, request->getRequestDataSize())
@ -384,16 +350,86 @@ static int processPutTask(HttpRequest *request, write_callback callback, void *s
} }
//Process DELETE Request //Process DELETE Request
static int processDeleteTask(HttpRequest *request, write_callback callback, void *stream, long *responseCode, write_callback headerCallback, void *headerStream) static int processDeleteTask(HttpRequest *request, write_callback callback, void *stream, long *responseCode, write_callback headerCallback, void *headerStream, char *errorBuffer)
{ {
CURLRaii curl; CURLRaii curl;
bool ok = curl.init(request, callback, stream, headerCallback, headerStream) bool ok = curl.init(request, callback, stream, headerCallback, headerStream, errorBuffer)
&& curl.setOption(CURLOPT_CUSTOMREQUEST, "DELETE") && curl.setOption(CURLOPT_CUSTOMREQUEST, "DELETE")
&& curl.setOption(CURLOPT_FOLLOWLOCATION, true) && curl.setOption(CURLOPT_FOLLOWLOCATION, true)
&& curl.perform(responseCode); && curl.perform(responseCode);
return ok ? 0 : 1; return ok ? 0 : 1;
} }
// Process Response
static void processResponse(HttpResponse* response, char* errorBuffer)
{
auto request = response->getHttpRequest();
long responseCode = -1;
int retValue = 0;
// Process the request -> get response packet
switch (request->getRequestType())
{
case HttpRequest::Type::GET: // HTTP GET
retValue = processGetTask(request,
writeData,
response->getResponseData(),
&responseCode,
writeHeaderData,
response->getResponseHeader(),
errorBuffer);
break;
case HttpRequest::Type::POST: // HTTP POST
retValue = processPostTask(request,
writeData,
response->getResponseData(),
&responseCode,
writeHeaderData,
response->getResponseHeader(),
errorBuffer);
break;
case HttpRequest::Type::PUT:
retValue = processPutTask(request,
writeData,
response->getResponseData(),
&responseCode,
writeHeaderData,
response->getResponseHeader(),
errorBuffer);
break;
case HttpRequest::Type::DELETE:
retValue = processDeleteTask(request,
writeData,
response->getResponseData(),
&responseCode,
writeHeaderData,
response->getResponseHeader(),
errorBuffer);
break;
default:
CCASSERT(true, "CCHttpClient: unkown request type, only GET and POSt are supported");
break;
}
// write data to HttpResponse
response->setResponseCode(responseCode);
if (retValue != 0)
{
response->setSucceed(false);
response->setErrorBuffer(errorBuffer);
}
else
{
response->setSucceed(true);
}
}
// HttpClient implementation // HttpClient implementation
HttpClient* HttpClient::getInstance() HttpClient* HttpClient::getInstance()
{ {
@ -429,7 +465,7 @@ HttpClient::~HttpClient()
s_need_quit = true; s_need_quit = true;
if (s_requestQueue != nullptr) { if (s_requestQueue != nullptr) {
s_SleepCondition.notify_one(); s_SleepCondition.notify_one();
} }
s_pHttpClient = nullptr; s_pHttpClient = nullptr;
@ -445,10 +481,10 @@ bool HttpClient::lazyInitThreadSemphore()
s_requestQueue = new Vector<HttpRequest*>(); s_requestQueue = new Vector<HttpRequest*>();
s_responseQueue = new Vector<HttpResponse*>(); s_responseQueue = new Vector<HttpResponse*>();
s_need_quit = false;
auto t = std::thread(CC_CALLBACK_0(HttpClient::networkThread, this)); auto t = std::thread(CC_CALLBACK_0(HttpClient::networkThread, this));
t.detach(); t.detach();
s_need_quit = false;
} }
return true; return true;
@ -479,6 +515,18 @@ void HttpClient::send(HttpRequest* request)
} }
} }
void HttpClient::sendImmediate(HttpRequest* request)
{
if(!request)
{
return;
}
request->retain();
auto t = std::thread(&HttpClient::networkThreadAlone, this, request);
t.detach();
}
// Poll and notify main thread if responses exists in queue // Poll and notify main thread if responses exists in queue
void HttpClient::dispatchResponseCallbacks() void HttpClient::dispatchResponseCallbacks()
{ {
@ -516,6 +564,8 @@ void HttpClient::dispatchResponseCallbacks()
} }
response->release(); response->release();
// do not release in other thread
request->release();
} }
} }

View File

@ -62,6 +62,13 @@ public:
please make sure request->_requestData is clear before calling "send" here. please make sure request->_requestData is clear before calling "send" here.
*/ */
void send(HttpRequest* request); void send(HttpRequest* request);
/**
* Immediate send a request
* @param request a HttpRequest object, which includes url, response callback etc.
please make sure request->_requestData is clear before calling "sendImmediate" here.
*/
void sendImmediate(HttpRequest* request);
/** /**
@ -101,6 +108,7 @@ private:
*/ */
bool lazyInitThreadSemphore(); bool lazyInitThreadSemphore();
void networkThread(); void networkThread();
void networkThreadAlone(HttpRequest* request);
/** Poll function called from main thread to dispatch callbacks when http requests finished **/ /** Poll function called from main thread to dispatch callbacks when http requests finished **/
void dispatchResponseCallbacks(); void dispatchResponseCallbacks();

View File

@ -13,6 +13,9 @@ HttpClientTest::HttpClientTest()
const int MARGIN = 40; const int MARGIN = 40;
const int SPACE = 35; const int SPACE = 35;
const int LEFT = winSize.width / 4;
const int RIGHT = winSize.width / 4 * 3;
auto label = Label::createWithTTF("Http Request Test", "fonts/arial.ttf", 28); auto label = Label::createWithTTF("Http Request Test", "fonts/arial.ttf", 28);
label->setPosition(Vec2(winSize.width / 2, winSize.height - MARGIN)); label->setPosition(Vec2(winSize.width / 2, winSize.height - MARGIN));
@ -24,36 +27,66 @@ HttpClientTest::HttpClientTest()
// Get // Get
auto labelGet = Label::createWithTTF("Test Get", "fonts/arial.ttf", 22); auto labelGet = Label::createWithTTF("Test Get", "fonts/arial.ttf", 22);
auto itemGet = MenuItemLabel::create(labelGet, CC_CALLBACK_1(HttpClientTest::onMenuGetTestClicked, this)); auto itemGet = MenuItemLabel::create(labelGet, CC_CALLBACK_1(HttpClientTest::onMenuGetTestClicked, this, false));
itemGet->setPosition(Vec2(winSize.width / 2, winSize.height - MARGIN - SPACE)); itemGet->setPosition(Vec2(LEFT, winSize.height - MARGIN - SPACE));
menuRequest->addChild(itemGet); menuRequest->addChild(itemGet);
// Post // Post
auto labelPost = Label::createWithTTF("Test Post", "fonts/arial.ttf", 22); auto labelPost = Label::createWithTTF("Test Post", "fonts/arial.ttf", 22);
auto itemPost = MenuItemLabel::create(labelPost, CC_CALLBACK_1(HttpClientTest::onMenuPostTestClicked, this)); auto itemPost = MenuItemLabel::create(labelPost, CC_CALLBACK_1(HttpClientTest::onMenuPostTestClicked, this, false));
itemPost->setPosition(Vec2(winSize.width / 2, winSize.height - MARGIN - 2 * SPACE)); itemPost->setPosition(Vec2(LEFT, winSize.height - MARGIN - 2 * SPACE));
menuRequest->addChild(itemPost); menuRequest->addChild(itemPost);
// Post Binary // Post Binary
auto labelPostBinary = Label::createWithTTF("Test Post Binary", "fonts/arial.ttf", 22); auto labelPostBinary = Label::createWithTTF("Test Post Binary", "fonts/arial.ttf", 22);
auto itemPostBinary = MenuItemLabel::create(labelPostBinary, CC_CALLBACK_1(HttpClientTest::onMenuPostBinaryTestClicked, this)); auto itemPostBinary = MenuItemLabel::create(labelPostBinary, CC_CALLBACK_1(HttpClientTest::onMenuPostBinaryTestClicked, this, false));
itemPostBinary->setPosition(Vec2(winSize.width / 2, winSize.height - MARGIN - 3 * SPACE)); itemPostBinary->setPosition(Vec2(LEFT, winSize.height - MARGIN - 3 * SPACE));
menuRequest->addChild(itemPostBinary); menuRequest->addChild(itemPostBinary);
// Put // Put
auto labelPut = Label::createWithTTF("Test Put", "fonts/arial.ttf", 22); auto labelPut = Label::createWithTTF("Test Put", "fonts/arial.ttf", 22);
auto itemPut = MenuItemLabel::create(labelPut, CC_CALLBACK_1(HttpClientTest::onMenuPutTestClicked, this)); auto itemPut = MenuItemLabel::create(labelPut, CC_CALLBACK_1(HttpClientTest::onMenuPutTestClicked, this, false));
itemPut->setPosition(Vec2(winSize.width / 2, winSize.height - MARGIN - 4 * SPACE)); itemPut->setPosition(Vec2(LEFT, winSize.height - MARGIN - 4 * SPACE));
menuRequest->addChild(itemPut); menuRequest->addChild(itemPut);
// Delete // Delete
auto labelDelete = Label::createWithTTF("Test Delete", "fonts/arial.ttf", 22); auto labelDelete = Label::createWithTTF("Test Delete", "fonts/arial.ttf", 22);
auto itemDelete = MenuItemLabel::create(labelDelete, CC_CALLBACK_1(HttpClientTest::onMenuDeleteTestClicked, this)); auto itemDelete = MenuItemLabel::create(labelDelete, CC_CALLBACK_1(HttpClientTest::onMenuDeleteTestClicked, this, false));
itemDelete->setPosition(Vec2(winSize.width / 2, winSize.height - MARGIN - 5 * SPACE)); itemDelete->setPosition(Vec2(LEFT, winSize.height - MARGIN - 5 * SPACE));
menuRequest->addChild(itemDelete);
// Get for sendImmediate
labelGet = Label::createWithTTF("Test Immediate Get", "fonts/arial.ttf", 22);
itemGet = MenuItemLabel::create(labelGet, CC_CALLBACK_1(HttpClientTest::onMenuGetTestClicked, this, true));
itemGet->setPosition(Vec2(RIGHT, winSize.height - MARGIN - SPACE));
menuRequest->addChild(itemGet);
// Post for sendImmediate
labelPost = Label::createWithTTF("Test Immediate Post", "fonts/arial.ttf", 22);
itemPost = MenuItemLabel::create(labelPost, CC_CALLBACK_1(HttpClientTest::onMenuPostTestClicked, this, true));
itemPost->setPosition(Vec2(RIGHT, winSize.height - MARGIN - 2 * SPACE));
menuRequest->addChild(itemPost);
// Post Binary for sendImmediate
labelPostBinary = Label::createWithTTF("Test Immediate Post Binary", "fonts/arial.ttf", 22);
itemPostBinary = MenuItemLabel::create(labelPostBinary, CC_CALLBACK_1(HttpClientTest::onMenuPostBinaryTestClicked, this, true));
itemPostBinary->setPosition(Vec2(RIGHT, winSize.height - MARGIN - 3 * SPACE));
menuRequest->addChild(itemPostBinary);
// Put for sendImmediate
labelPut = Label::createWithTTF("Test Immediate Put", "fonts/arial.ttf", 22);
itemPut = MenuItemLabel::create(labelPut, CC_CALLBACK_1(HttpClientTest::onMenuPutTestClicked, this, true));
itemPut->setPosition(Vec2(RIGHT, winSize.height - MARGIN - 4 * SPACE));
menuRequest->addChild(itemPut);
// Delete for sendImmediate
labelDelete = Label::createWithTTF("Test Immediate Delete", "fonts/arial.ttf", 22);
itemDelete = MenuItemLabel::create(labelDelete, CC_CALLBACK_1(HttpClientTest::onMenuDeleteTestClicked, this, true));
itemDelete->setPosition(Vec2(RIGHT, winSize.height - MARGIN - 5 * SPACE));
menuRequest->addChild(itemDelete); menuRequest->addChild(itemDelete);
// Response Code Label // Response Code Label
_labelStatusCode = Label::createWithTTF("HTTP Status Code", "fonts/arial.ttf", 22); _labelStatusCode = Label::createWithTTF("HTTP Status Code", "fonts/arial.ttf", 18);
_labelStatusCode->setPosition(Vec2(winSize.width / 2, winSize.height - MARGIN - 6 * SPACE)); _labelStatusCode->setPosition(Vec2(winSize.width / 2, winSize.height - MARGIN - 6 * SPACE));
addChild(_labelStatusCode); addChild(_labelStatusCode);
@ -70,7 +103,7 @@ HttpClientTest::~HttpClientTest()
HttpClient::destroyInstance(); HttpClient::destroyInstance();
} }
void HttpClientTest::onMenuGetTestClicked(cocos2d::Ref *sender) void HttpClientTest::onMenuGetTestClicked(cocos2d::Ref *sender, bool isImmediate)
{ {
// test 1 // test 1
{ {
@ -78,8 +111,15 @@ void HttpClientTest::onMenuGetTestClicked(cocos2d::Ref *sender)
request->setUrl("http://just-make-this-request-failed.com"); request->setUrl("http://just-make-this-request-failed.com");
request->setRequestType(HttpRequest::Type::GET); request->setRequestType(HttpRequest::Type::GET);
request->setResponseCallback(CC_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); request->setResponseCallback(CC_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this));
request->setTag("GET test1"); if (isImmediate)
HttpClient::getInstance()->send(request); {
request->setTag("GET immediate test1");
HttpClient::getInstance()->sendImmediate(request);
}else
{
request->setTag("GET test1");
HttpClient::getInstance()->send(request);
}
request->release(); request->release();
} }
@ -90,11 +130,15 @@ void HttpClientTest::onMenuGetTestClicked(cocos2d::Ref *sender)
request->setUrl("http://httpbin.org/ip"); request->setUrl("http://httpbin.org/ip");
request->setRequestType(HttpRequest::Type::GET); request->setRequestType(HttpRequest::Type::GET);
request->setResponseCallback(CC_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); request->setResponseCallback(CC_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this));
// optional fields if (isImmediate)
request->setTag("GET test2"); {
request->setTag("GET immediate test2");
HttpClient::getInstance()->send(request); HttpClient::getInstance()->sendImmediate(request);
}else
{
request->setTag("GET test2");
HttpClient::getInstance()->send(request);
}
// don't forget to release it, pair to new // don't forget to release it, pair to new
request->release(); request->release();
} }
@ -105,8 +149,15 @@ void HttpClientTest::onMenuGetTestClicked(cocos2d::Ref *sender)
request->setUrl("https://httpbin.org/get"); request->setUrl("https://httpbin.org/get");
request->setRequestType(HttpRequest::Type::GET); request->setRequestType(HttpRequest::Type::GET);
request->setResponseCallback(CC_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); request->setResponseCallback(CC_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this));
request->setTag("GET test3"); if (isImmediate)
HttpClient::getInstance()->send(request); {
request->setTag("GET immediate test3");
HttpClient::getInstance()->sendImmediate(request);
}else
{
request->setTag("GET test3");
HttpClient::getInstance()->send(request);
}
request->release(); request->release();
} }
@ -115,7 +166,7 @@ void HttpClientTest::onMenuGetTestClicked(cocos2d::Ref *sender)
} }
void HttpClientTest::onMenuPostTestClicked(cocos2d::Ref *sender) void HttpClientTest::onMenuPostTestClicked(cocos2d::Ref *sender, bool isImmediate)
{ {
// test 1 // test 1
{ {
@ -127,9 +178,15 @@ void HttpClientTest::onMenuPostTestClicked(cocos2d::Ref *sender)
// write the post data // write the post data
const char* postData = "visitor=cocos2d&TestSuite=Extensions Test/NetworkTest"; const char* postData = "visitor=cocos2d&TestSuite=Extensions Test/NetworkTest";
request->setRequestData(postData, strlen(postData)); request->setRequestData(postData, strlen(postData));
if (isImmediate)
request->setTag("POST test1"); {
HttpClient::getInstance()->send(request); request->setTag("POST immediate test1");
HttpClient::getInstance()->sendImmediate(request);
}else
{
request->setTag("POST test1");
HttpClient::getInstance()->send(request);
}
request->release(); request->release();
} }
@ -146,9 +203,15 @@ void HttpClientTest::onMenuPostTestClicked(cocos2d::Ref *sender)
// write the post data // write the post data
const char* postData = "visitor=cocos2d&TestSuite=Extensions Test/NetworkTest"; const char* postData = "visitor=cocos2d&TestSuite=Extensions Test/NetworkTest";
request->setRequestData(postData, strlen(postData)); request->setRequestData(postData, strlen(postData));
if (isImmediate)
request->setTag("POST test2"); {
HttpClient::getInstance()->send(request); request->setTag("POST immediate test2");
HttpClient::getInstance()->sendImmediate(request);
}else
{
request->setTag("POST test2");
HttpClient::getInstance()->send(request);
}
request->release(); request->release();
} }
@ -156,7 +219,7 @@ void HttpClientTest::onMenuPostTestClicked(cocos2d::Ref *sender)
_labelStatusCode->setString("waiting..."); _labelStatusCode->setString("waiting...");
} }
void HttpClientTest::onMenuPostBinaryTestClicked(cocos2d::Ref *sender) void HttpClientTest::onMenuPostBinaryTestClicked(cocos2d::Ref *sender, bool isImmediate)
{ {
HttpRequest* request = new HttpRequest(); HttpRequest* request = new HttpRequest();
request->setUrl("http://httpbin.org/post"); request->setUrl("http://httpbin.org/post");
@ -166,9 +229,15 @@ void HttpClientTest::onMenuPostBinaryTestClicked(cocos2d::Ref *sender)
// write the post data // write the post data
char postData[22] = "binary=hello\0\0cocos2d"; // including \0, the strings after \0 should not be cut in response char postData[22] = "binary=hello\0\0cocos2d"; // including \0, the strings after \0 should not be cut in response
request->setRequestData(postData, 22); request->setRequestData(postData, 22);
if (isImmediate)
request->setTag("POST Binary test"); {
HttpClient::getInstance()->send(request); request->setTag("POST Binary immediate test");
HttpClient::getInstance()->sendImmediate(request);
}else
{
request->setTag("POST Binary test");
HttpClient::getInstance()->send(request);
}
request->release(); request->release();
// waiting // waiting
@ -177,7 +246,7 @@ void HttpClientTest::onMenuPostBinaryTestClicked(cocos2d::Ref *sender)
void HttpClientTest::onMenuPutTestClicked(Ref *sender) void HttpClientTest::onMenuPutTestClicked(Ref *sender, bool isImmediate)
{ {
// test 1 // test 1
{ {
@ -189,9 +258,15 @@ void HttpClientTest::onMenuPutTestClicked(Ref *sender)
// write the post data // write the post data
const char* postData = "visitor=cocos2d&TestSuite=Extensions Test/NetworkTest"; const char* postData = "visitor=cocos2d&TestSuite=Extensions Test/NetworkTest";
request->setRequestData(postData, strlen(postData)); request->setRequestData(postData, strlen(postData));
if (isImmediate)
request->setTag("PUT test1"); {
HttpClient::getInstance()->send(request); request->setTag("PUT Binary immediate test1");
HttpClient::getInstance()->sendImmediate(request);
}else
{
request->setTag("PUT Binary test1");
HttpClient::getInstance()->send(request);
}
request->release(); request->release();
} }
@ -208,9 +283,15 @@ void HttpClientTest::onMenuPutTestClicked(Ref *sender)
// write the post data // write the post data
const char* postData = "visitor=cocos2d&TestSuite=Extensions Test/NetworkTest"; const char* postData = "visitor=cocos2d&TestSuite=Extensions Test/NetworkTest";
request->setRequestData(postData, strlen(postData)); request->setRequestData(postData, strlen(postData));
if (isImmediate)
request->setTag("PUT test2"); {
HttpClient::getInstance()->send(request); request->setTag("PUT Binary immediate test2");
HttpClient::getInstance()->sendImmediate(request);
}else
{
request->setTag("PUT Binary test2");
HttpClient::getInstance()->send(request);
}
request->release(); request->release();
} }
@ -218,7 +299,7 @@ void HttpClientTest::onMenuPutTestClicked(Ref *sender)
_labelStatusCode->setString("waiting..."); _labelStatusCode->setString("waiting...");
} }
void HttpClientTest::onMenuDeleteTestClicked(Ref *sender) void HttpClientTest::onMenuDeleteTestClicked(Ref *sender, bool isImmediate)
{ {
// test 1 // test 1
{ {
@ -226,8 +307,15 @@ void HttpClientTest::onMenuDeleteTestClicked(Ref *sender)
request->setUrl("http://just-make-this-request-failed.com"); request->setUrl("http://just-make-this-request-failed.com");
request->setRequestType(HttpRequest::Type::DELETE); request->setRequestType(HttpRequest::Type::DELETE);
request->setResponseCallback(CC_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); request->setResponseCallback(CC_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this));
request->setTag("DELETE test1"); if (isImmediate)
HttpClient::getInstance()->send(request); {
request->setTag("DELETE immediate test1");
HttpClient::getInstance()->sendImmediate(request);
}else
{
request->setTag("DELETE test1");
HttpClient::getInstance()->send(request);
}
request->release(); request->release();
} }
@ -237,8 +325,15 @@ void HttpClientTest::onMenuDeleteTestClicked(Ref *sender)
request->setUrl("http://httpbin.org/delete"); request->setUrl("http://httpbin.org/delete");
request->setRequestType(HttpRequest::Type::DELETE); request->setRequestType(HttpRequest::Type::DELETE);
request->setResponseCallback(CC_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); request->setResponseCallback(CC_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this));
request->setTag("DELETE test2"); if (isImmediate)
HttpClient::getInstance()->send(request); {
request->setTag("DELETE immediate test2");
HttpClient::getInstance()->sendImmediate(request);
}else
{
request->setTag("DELETE test2");
HttpClient::getInstance()->send(request);
}
request->release(); request->release();
} }
@ -280,6 +375,10 @@ void HttpClientTest::onHttpRequestCompleted(HttpClient *sender, HttpResponse *re
printf("%c", (*buffer)[i]); printf("%c", (*buffer)[i]);
} }
printf("\n"); printf("\n");
if (response->getHttpRequest()->getReferenceCount() != 2)
{
log("request ref count not 2, is %d", response->getHttpRequest()->getReferenceCount());
}
} }
void HttpClientTest::toExtensionsMainLayer(cocos2d::Ref *sender) void HttpClientTest::toExtensionsMainLayer(cocos2d::Ref *sender)

View File

@ -13,11 +13,11 @@ public:
void toExtensionsMainLayer(cocos2d::Ref *sender); void toExtensionsMainLayer(cocos2d::Ref *sender);
//Menu Callbacks //Menu Callbacks
void onMenuGetTestClicked(cocos2d::Ref *sender); void onMenuGetTestClicked(cocos2d::Ref *sender, bool isImmediate);
void onMenuPostTestClicked(cocos2d::Ref *sender); void onMenuPostTestClicked(cocos2d::Ref *sender, bool isImmediate);
void onMenuPostBinaryTestClicked(cocos2d::Ref *sender); void onMenuPostBinaryTestClicked(cocos2d::Ref *sender, bool isImmediate);
void onMenuPutTestClicked(cocos2d::Ref *sender); void onMenuPutTestClicked(cocos2d::Ref *sender, bool isImmediate);
void onMenuDeleteTestClicked(cocos2d::Ref *sender); void onMenuDeleteTestClicked(cocos2d::Ref *sender, bool isImmediate);
//Http Response Callback //Http Response Callback
void onHttpRequestCompleted(cocos2d::network::HttpClient *sender, cocos2d::network::HttpResponse *response); void onHttpRequestCompleted(cocos2d::network::HttpClient *sender, cocos2d::network::HttpResponse *response);