不知道为什么cocos2dx中似乎没有把extensions/network里的HttpClient集成进去,自己试了一下DIY也不是很难,现总结如下
首先CCHttpRequest中的setResponseCallback需要处理一下,因为这里我们需要的是一个lua的回调而并非c++的,
处理方案参考CCSchduler中的scheduleScriptFunc,采用lua的handler来解决
最终代码如下:
pkg文件
class CCHttpClient : CCObject { static CCHttpClient *getInstance(); static void destroyInstance(); void send(CCHttpRequest* request); void setTimeoutForConnect(int value); int getTimeoutForConnect(); void setTimeoutForRead(int value); int getTimeoutForRead(); }; class CCHttpRequest : CCObject { typedef enum { kHttpGet, kHttpPost, kHttpPut, kHttpDelete, kHttpUnkown, } HttpRequestType; void setRequestType(HttpRequestType type); HttpRequestType getRequestType(); void setUrl(const char* url); const char* getUrl(); void setRequestData(const char* buffer, unsigned int len); char* getRequestData(); int getRequestDataSize(); void setTag(const char* tag); const char* getTag(); }; class CCLuaHttpRequest: CCHttpRequest { void setResponseScriptCallback(LUA_FUNCTION aHandler); static CCLuaHttpRequest* create(); static bool mkdirs(std::string aDir); };
#ifndef CCLUAHTTPREQUEST_H_ #define CCLUAHTTPREQUEST_H_ #include <network/HttpClient.h> USING_NS_CC; USING_NS_CC_EXT; class CCLuaHttpRequest: public CCHttpRequest { public: CCLuaHttpRequest(); virtual ~CCLuaHttpRequest(); public: static CCLuaHttpRequest* create(); static bool mkdirs(std::string aDir); /** * 设置一个用于回调的lua函数 */ void setResponseScriptCallback(unsigned int aHandler); private: /** * 默认的用于c++的回调,由这里统一处理到lua的回调 */ void responseScriptCallback(CCHttpClient* apClient, CCHttpResponse* apResponse); private: /** * 当前保存的handler */ unsigned int mHandler; }; #endif /* CCLUAHTTPREQUEST_H_ */
#include "LuaHttpRequest.h" #include "CCLuaEngine.h" #include <sys/stat.h> #include <sys/types.h> #include <errno.h> CCLuaHttpRequest::CCLuaHttpRequest() : mHandler(0) { } CCLuaHttpRequest::~CCLuaHttpRequest() { } CCLuaHttpRequest* CCLuaHttpRequest::create() { return new CCLuaHttpRequest; } bool CCLuaHttpRequest::mkdirs(std::string aDir) { if (aDir.size() == 0) { return true; } CCLOG("creating dir:%s", aDir.c_str()); bool isFirst = aDir[0] == '/'; bool isLast = false; for (unsigned int i = 1; i < aDir.size(); i++) { if (aDir[i] == '/') { if (isLast) { continue; } isLast = true; if (isFirst) { isFirst = false; continue; } std::string path = aDir.substr(0, i); if (CCFileUtils::sharedFileUtils()->isFileExist(path.c_str())) { CCLOG("path:%s exist", path.c_str()); continue; } int ret = mkdir(path.c_str(), 0700); if (ret && errno != EEXIST) { CCLOG("mkdir:%s failed", path.c_str()); return false; } else { CCLOG("path:%s created", path.c_str()); } } else { isLast = false; } } return true; } void CCLuaHttpRequest::setResponseScriptCallback(unsigned int aHandler) { mHandler = aHandler; setResponseCallback(this, httpresponse_selector(CCLuaHttpRequest::responseScriptCallback)); } void CCLuaHttpRequest::responseScriptCallback(CCHttpClient* apClient, CCHttpResponse* apResponse) { CCLuaEngine* pEngine = dynamic_cast<CCLuaEngine*>(CCScriptEngineManager::sharedManager()->getScriptEngine()); CCLuaStack* pStack = pEngine->getLuaStack(); bool isSucceed = apResponse->isSucceed(); int status = apResponse->getResponseCode(); const char* errorBuffer = apResponse->getErrorBuffer(); std::vector<char>* headerBuffer = apResponse->getResponseHeader(); std::vector<char>* bodyBuffer = apResponse->getResponseData(); std::string header(headerBuffer->begin(), headerBuffer->end()); std::string body(bodyBuffer->begin(), bodyBuffer->end()); pStack->pushCCObject(apResponse->getHttpRequest(), "CCHttpRequest"); pStack->pushBoolean(isSucceed); //是否成功 pStack->pushString(body.c_str(), body.size()); //body pStack->pushString(header.c_str()); //header pStack->pushInt(status); //状态码 pStack->pushString(errorBuffer); //错误描述 pStack->executeFunctionByHandler(mHandler, 6); pStack->clean(); }
最终使用的lua代码如下
local request = CCLuaHttpRequest:create() request:setUrl(url) request:setTag(tag) request:setRequestType(CCHttpRequest.kHttpGet) request:setResponseScriptCallback(dlImageCallback) CCHttpClient:getInstance():send(request) request:release()