实现
该工具类对Cocos2d-x中的HttpClient进行了封装,使可以在Lua中实现http异步请求。
#ifndef __LUAHTTPCLIENT_H__
#define __LUAHTTPCLIENT_H__
#include "cocos2d.h"
USING_NS_CC;
#include "cocos-ext.h"
USING_NS_CC_EXT;
// 参数封装类
class LuaParams{
public:
static LuaParams* create(){
LuaParams* params = new LuaParams(); // 参数在回调后释放
params->setTypeName("nil");
return params;
};
static LuaParams* create(const char* url,
int func,
const char* data,
CCObject* obj ,
const char* typeName = "nil"){
LuaParams* params = new LuaParams();
params->setData(data);
params->setUrl(url);
params->setFunc(func);
params->setCCObjct(obj);
params->setTypeName(typeName);
return params;
};
void setFunc(int func_){
func = func_;
};
int getFunc(){
return func;
};
void setCCObjct(CCObject* obj_){
obj = obj_;
};
CCObject* getCCObjct(){
return obj;
};
void setTypeName(const char* typeName_){
typeName = typeName_;
};
const char* getTypeName(){
return typeName.c_str();
};
void setUrl(const char* url_){
url = url_;
};
const char* getUrl(){
return url;
};
void setData(const char* data_){
data = data_;
};
const char* getData(){
return data;
};
private:
/** POST请求数据 **/
const char* data;
/** 请求地址 **/
const char* url;
/** Lua回调方法 **/
int func;
/** 用户数据 **/
CCObject* obj;
/** 用户数据类型名称 **/
std::string typeName;
};
// Lua异步http请求工具类
class LuaHttpClient:public CCObject{
public:
// 单例
static LuaHttpClient* getInstance();
// 异步Get请求
void asynGet(LuaParams* params);
// 异步Post请求
void asynPost(LuaParams* params);
// 回调函数
void callback(CCHttpClient *sender, CCHttpResponse *response);
};
#endif
#include "LuaHttpClient.h"
#include "../cocos2dx_support/CCLuaEngine.h"
static LuaHttpClient* s_instance = NULL;
LuaHttpClient* LuaHttpClient::getInstance(){
if (s_instance == NULL)
{
s_instance = new LuaHttpClient();
s_instance->autorelease();
}
return s_instance;
}
void LuaHttpClient::asynGet(LuaParams* params){
CCHttpRequest* request = new CCHttpRequest();
request->setUrl(params->getUrl());
request->setRequestType(CCHttpRequest::kHttpGet);
request->setResponseCallback(this, httpresponse_selector(LuaHttpClient::callback));
request->setUserData((void*)params);
CCHttpClient::getInstance()->send(request);
if (params->getTypeName() != "nil")
{
params->getCCObjct()->retain(); //引用计数+1
}
}
void LuaHttpClient::asynPost(LuaParams* params){
CCHttpRequest* request = new CCHttpRequest();
request->setUrl(params->getUrl());
request->setRequestType(CCHttpRequest::kHttpPost);
request->setResponseCallback(this, httpresponse_selector(LuaHttpClient::callback));
request->setUserData((void*)params);
// write the post data
request->setRequestData(params->getData(), strlen(params->getData()));
CCHttpClient::getInstance()->send(request);
request->release();
if (params->getTypeName() != "nil")
{
params->getCCObjct()->retain(); //引用计数+1
}
}
void LuaHttpClient::callback(CCHttpClient *sender, CCHttpResponse *response){
if (!response)
{
return;
}
int statusCode = response->getResponseCode();
char statusString[64] = {};
sprintf(statusString, "HTTP Status Code: %d, tag = %s", statusCode, response->getHttpRequest()->getTag());
CCLog("response code: %d", statusCode);
// 回调Lua函数
LuaParams* params = (LuaParams*)response->getHttpRequest()->getUserData();
CCLuaStack* pStack = CCLuaEngine::defaultEngine()->getLuaStack();
if (!response->isSucceed())
{
CCLog("response failed");
CCLog("error buffer: %s", response->getErrorBuffer());
pStack->pushInt(statusCode); //请求失败,返回错误码到回调函数
if (params->getTypeName() != "nil")
{
// 如果传递了CCObject,把它作为第二个参数
pStack->pushCCObject(params->getCCObjct(),params->getTypeName());
pStack->executeFunctionByHandler(params->getFunc(),2);
pStack->clean();
params->getCCObjct()->release(); //引用计数-1
}else{
pStack->executeFunctionByHandler(params->getFunc(),1);
pStack->clean();
}
delete params;
return;
}
// dump data
std::vector
*buffer = response->getResponseData();
std::string data (buffer->begin(),buffer->end());
CCLOG("request success");
pStack->pushString(data.c_str()); //把服务器回应的数据添加到函数参数1
//if (params->getCCObjct() && params->getTypeName()) //这个判断不知道为什么有一定随机性
if (params->getTypeName() != "nil")
{
// 如果传递了CCObject,把它作为第二个参数
pStack->pushCCObject(params->getCCObjct(),params->getTypeName());
pStack->executeFunctionByHandler(params->getFunc(),2);
pStack->clean();
params->getCCObjct()->release(); //引用计数-1
}else{
//第一个参数是函数的整数句柄,第二个参数是函数参数个数
pStack->executeFunctionByHandler(params->getFunc(),1);
pStack->clean();
}
delete params;
}
绑定到Lua
工程地址:https://coding.net/u/linchaolong/p/Cocos2d-x_LuaHttpClient/git
该工程使用cocos2d-x-2.2.6和vs2012
把工程放到引擎projects目录下即可
1.把“绑定自定义类到lua”目录下的ext文件夹放到cocos2d-x-2.2.6\scripting\lua目录下
2.其它文件放到cocos2d-x-2.2.6\tools\tolua++目录下,点击build_ext.bat生成绑定文件
3.把LuaExt.h和LuaExt.cpp放到cocos2d-x-2.2.6\scripting\lua\cocos2dx_support下
4.修改CCLuaStack.cpp,在init方法下调用tolua_Ext_open方法注册自定义C++类
#include "LuaExt.h" //包含头文件
m_state = lua_open();
luaL_openlibs(m_state);
tolua_Cocos2d_open(m_state);
tolua_Ext_open(m_state); //注册自定义类
toluafix_open(m_state);
5.在项目中引入文件
调用示例
在Lua中调用的示例代码
-- 在主线程中创建一个CCLayer
local layer2 = CCLayerColor:create(ccc4(200,0,0,200))
-- 回调函数(参数1:服务返回的数据,参数2:用户数据(CCObject))
local callback = function(responseData, userdata)
cclog("lua response data : %s",responseData)
-- 替换场景
local scene = CCScene:create()
scene:addChild(userdata) -- 添加主线程中创建的CCLayer到场景
CCDirector:sharedDirector():replaceScene(scene)
end
-- 1.异步http get请求并,传递一个CCObject
local params = LuaParams:create("http://www.baidu.com",callback,"",layer2,"CCLayer")
-- 2.异步http get请求
-- local params = LuaParams:create()
-- params:setUrl("http://www.baidu.com")
-- params:setFunc(callback)
LuaHttpClient:getInstance():asynGet(params) --发起请求