cocos2d-x学习篇之网络(http)篇

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

转自:http://blog.csdn.net/duotianshi86/article/details/10216383

这段时间接触到cocos2d-x,拜读了csdn上很多大大的文章,尤其是小满的专栏,感觉获益不少,觉得像他们那样,边学习,边总结经验,并写出来学习过程与大家分享,我觉得是一件很值得学习的事,所以也打算把自己学习的东西和经验与大家分享,有不足之处或者错误的,还希望请大家能海涵并提出来,共同讨论,共同进步。好了,废话到此。

Cocos2dx 为我们封装了在cocos2dx中http的网络框架,其文件在cocos2dx引擎包的cocos2d-2.1rc0-x-2.1.2\extensions\network文件下的 HttpClient、HttpRequest 、HttpResponse。但是真正的底层,用的还是cURL库。。。

进行一次http交互,需要涉及的有三个类,HttpRequest用来描述一个请求。HttpResponse用来描述对应请求的响应。HttpClient是一个单例模式的类,它的职责就是负责将收到的HttpRequest对象push到发送队列中,并发送一个信号量驱动工作线程工作,工作线程再将收到的数据封装成一个HttpResponse对象push接收队列,并启用调度来派送数据。具体的后面有说道。

1.首先创建一个类,继承自cocos2d-x中的任何一个类都可以(有共同父类CCObject),并实现一个SEL_CallFuncND类型成员函数,用来做收到数据后的回调函数,函数原型为void fun(CCNode*, void*)。

2.当我们需要一次http交互的时候,我们需要new 一个CCHttpRequest对象,并设置url和请求方式(get还是post,本文只说一下get的原理,post区别不大,可以自己看),并将上面说函数设置为收到数据后的回调函数。

3.使用CCHttpClient::getInstance()单例对象,将前一步骤的CCHttpRequest对象作为参数,调用send()方法。

4.在回调函数中,将第二个参数转换成CCHttpResponse *类型,就可以通过CCHttpResponse类的方法来获取返回状态和数据等能容了。

我们先来看看具体的该怎么用,以自带的HttpClientTest.cpp为例。HttpClientTest.cpp:

[cpp]  view plain copy
  1. //get请求  
  2. void HttpClientTest::onMenuGetTestClicked(cocos2d::CCObject *sender)  
  3. {      
  4.     // test 1  
  5.     {  
  6.         CCHttpRequest* request = new CCHttpRequest();//创建request对象,这里new出来的对象不能使用autorelease(),原因后述  
  7.         request->setUrl("http://just-make-this-request-failed.com");//设置url  
  8.         request->setRequestType(CCHttpRequest::kHttpGet);//设置请求方式  
  9.         request->setResponseCallback(this, callfuncND_selector(HttpClientTest::onHttpRequestCompleted));//这是回调对象和回调函数  
  10.         request->setTag("GET test1");//设置用户标识,可以通过response获取  
  11.         CCHttpClient::getInstance()->send(request);//使用CCHttpClient共享实例来发送request  
  12.         request->release();//调用release()  
  13.     }  
  14.   
  15.     // waiting  
  16.     m_labelStatusCode->setString("waiting...");  
  17.    
  18. }  
  19. //这里就是我们要处理接收到数据的回调函数了,sender为CCHttpClient实例指针,data为接收到的response指针  
  20. void HttpClientTest::onHttpRequestCompleted(cocos2d::CCNode *sender, void *data)  
  21. {  
  22.     CCHttpResponse *response = (CCHttpResponse*)data;  
  23.   
  24.     if (!response)  
  25.     {  
  26.         return;  
  27.     }  
  28.       
  29.     // 获取对应request的字符串标识  
  30.     if (0 != strlen(response->getHttpRequest()->getTag()))   
  31.     {  
  32.         CCLog("%s completed", response->getHttpRequest()->getTag());  
  33.     }  
  34.     //获取返回代码,比如200、404等  
  35.     int statusCode = response->getResponseCode();  
  36.     char statusString[64] = {};  
  37.     sprintf(statusString, "HTTP Status Code: %d, tag = %s", statusCode, response->getHttpRequest()->getTag());  
  38.     m_labelStatusCode->setString(statusString);  
  39.     CCLog("response code: %d", statusCode);  
  40.       
  41.     if (!response->isSucceed())   
  42.     {  
  43.         CCLog("response failed");  
  44.         CCLog("error buffer: %s", response->getErrorBuffer());//可以调用getErrorBuffer()来获取错误原因  
  45.         return;  
  46.     }  
  47.       
  48.     // dump data  
  49.     std::vector<char> *buffer = response->getResponseData();//用来获取接收到的数据  
  50.     printf("Http Test, dump data: ");  
  51.     for (unsigned int i = 0; i < buffer->size(); i++)  
  52.     {  
  53.         printf("%c", (*buffer)[i]);  
  54.     }  
  55.     printf("\n");  
  56. }  


基本上一个http交互就是这个样子了,下面我们深入的看一下CCHttpClient是怎么工作的,先来看一张图,画的不好或者不足之处,请勿拍砖

其实就是当我们第一次CCHttpClient::getInstance()时,CCHttpClient会将自己的成员函数dispathResponseCallbacks()挂载至CCScheduler(可以理解成一个调度者,它会定时调用所有挂载至上面的函数),并将它初始设置为停止调度。在当我们第一次调用send()发送数据时,CCHttpClient会创建一个工作线程(之后再调用send()就不会创建线程了),然后再将传递过来的CCHttpRequest对象push到发送队列s_requestQueue,并发送一个信号给工作线程,驱使其工作。工作线程首先从发送队列中取得一个CCHttpRequest对象,并new 一个CCHttpResponse对象,将参数设置给cURL,cURL会在获取到数据的填充response,工作线程将填充后的response再放到接收队列s_responseQueue中去,同时,启用调度。下一次CCScheduler就会CCHttpClient::dispatchResponseCallbacks()了,在该函数中,它会调用我们在第二步中设置给request的回调函数,并将response传递过去。基本过程就是这样。下面来详解相关的源文件。HttpRequest.h,其实这个文件没什么好说的,都有注释

[cpp]  view plain copy
  1. class CCHttpRequest : public CCObject  
  2. {  
  3. public:  
  4.     /** 请求类型枚举,可以通过setReqeustType(param) 设置*/  
  5.     typedef enum  
  6.     {  
  7.         kHttpGet,  
  8.         kHttpPost,  
  9.         kHttpUnkown,  
  10.     } HttpRequestType;  
  11.       
  12.     /** Constructor  
  13.         Because HttpRequest object will be used between UI thead and network thread, 
  14.         requestObj->autorelease() is forbidden to avoid crashes in CCAutoreleasePool 
  15.         new/retain/release still works, which means you need to release it manually 
  16.         Please refer to HttpRequestTest.cpp to find its usage 
  17.     这里是有注释的,因为要跨线程,所以就不能用autorelease() 
  18.     我们在使用HttpRequest的时候,需要自己new,然后再release下就可以了 
  19.     当我们把HttpRequest传递给CCHttpClient的时候,CCHttpClient已经帮我们retain了 
  20.     工作线程中,需要使用CCHttpRequest对象new一个CCHttpResponse,CCHttprequest会retain一次,所以工作线程也会release一次 
  21.     具体的后文有 
  22.      */  
  23.     CCHttpRequest()  
  24.     {  
  25.         _requestType = kHttpUnkown;  
  26.         _url.clear();  
  27.         _requestData.clear();  
  28.         _tag.clear();  
  29.         _pTarget = NULL;  
  30.         _pSelector = NULL;  
  31.         _pUserData = NULL;  
  32.     };  
  33.       
  34.     virtual ~CCHttpRequest()  
  35.     {  
  36.         if (_pTarget)  
  37.         {  
  38.             _pTarget->release();  
  39.         }  
  40.     };  
  41.       
  42.     /** 重载autorelease函数,禁止调用 */  
  43.     CCObject* autorelease(void)  
  44.     {  
  45.         CCAssert(false, "HttpResponse is used between network thread and ui thread \  
  46.                  therefore, autorelease is forbidden here");  
  47.         return NULL;  
  48.     }  
  49.               
  50.     // setter/getters for properties  
  51.        
  52.     /** 设置请求类型 
  53.         目前支持kHttpGet 和 kHttpPost 
  54.      */  
  55.     inline void setRequestType(HttpRequestType type)  
  56.     {  
  57.         _requestType = type;  
  58.     };  
  59.     /** 返回请求类型 */  
  60.     inline HttpRequestType getRequestType()  
  61.     {  
  62.         return _requestType;  
  63.     };  
  64.       
  65.     /** 设置请求url 
  66.      */  
  67.     inline void setUrl(const char* url)  
  68.     {  
  69.         _url = url;  
  70.     };  
  71.     /** 获取请求url */  
  72.     inline const char* getUrl()  
  73.     {  
  74.         return _url.c_str();  
  75.     };  
  76.       
  77.     /** 这个设置用于post方式的data数据 
  78.      */  
  79.     inline void setRequestData(const char* buffer, unsigned int len)  
  80.     {  
  81.         _requestData.assign(buffer, buffer + len);  
  82.     };  
  83.     /** Get the request data pointer back */  
  84.     inline char* getRequestData()  
  85.     {  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值