game2006/server/gameserver/httpproxy.cc

150 lines
5.3 KiB
C++

#include "precompile.h"
#include <a8/sysutils.h>
#include <a8/mutable_xobject.h>
#include "httpproxy.h"
#include "app.h"
#include "jsondatamgr.h"
#include "handlermgr.h"
#include "framework/cpp/httpclientpool.h"
struct HttpProxyRequest
{
std::string req_id;
a8::XParams param;
f8::AsyncHttpOnOkFunc on_ok;
f8::AsyncHttpOnErrorFunc on_error;
std::string url;
a8::XObject url_params;
long long add_tick = 0;
};
static void _ProxyCallback(f8::JsonHttpRequest* request)
{
//#ifdef DEBUG
a8::UdpLog::Instance()->Debug("ProxyCallbBack request:%s",
{
request->request.ToJsonStr()
});
//#endif
std::string seq_id = request->request.Get("seq_id");
HttpProxyRequest* req = HttpProxy::Instance()->GetRequest(seq_id);
if (req) {
a8::XObject data;
data.ReadFromJsonString(request->request.Get("data").GetString());
if (data.GetType() == a8::XOT_SIMPLE) {
data.ReadFromJsonString("{}");
}
if (request->request.HasKey("errcode") &&
request->request.Get("errcode").GetInt() == 0) {
req->on_ok(req->param, data);
} else {
req->on_error(req->param, data.Get("errmsg").GetString());
}
HttpProxy::Instance()->DestoryRequest(req);
}
}
void HttpProxy::Init()
{
request_prefix_ = "game2006_" + a8::XValue(a8::GetMilliSecond()).GetString() + "_";
HandlerMgr::Instance()->RegisterGMMsgHandler("Proxy@callback", _ProxyCallback);
}
void HttpProxy::UnInit()
{
}
std::string HttpProxy::HttpGet(a8::XParams param,
f8::AsyncHttpOnOkFunc on_ok,
f8::AsyncHttpOnErrorFunc on_error,
const char* url,
a8::XObject url_params
)
{
HttpProxyRequest* request = new HttpProxyRequest();
request->req_id = CreateRequestId();
request->param = param;
request->on_ok = on_ok;
request->on_error = on_error;
request->url = url;
request->url_params = url_params;
request->add_tick = a8::XGetTickCount();
if (request_hash_.find(request->req_id) != request_hash_.end()) {
abort();
}
request_hash_[request->req_id] = request;
auto proxy_url_params = a8::MutableXObject::CreateObject();
proxy_url_params->SetVal("seq_id", request->req_id);
proxy_url_params->SetVal("target_url", std::string(url));
proxy_url_params->SetVal("params", url_params.ToJsonStr());
proxy_url_params->SetVal("cb_url", a8::Format("http://%s:%d/webapp/index.php?c=Proxy&a=callback",
{
JsonDataMgr::Instance()->ip,
JsonDataMgr::Instance()->listen_port
}));
std::string proxy_url;
JsonDataMgr::Instance()->GetHttpProxyUrl(proxy_url);
f8::HttpClientPool::Instance()->HttpGet
(a8::XParams()
.SetSender(request->req_id),
[] (a8::XParams& param, a8::XObject& data)
{
HttpProxyRequest* req = HttpProxy::Instance()->GetRequest(param.sender.GetString());
if (req) {
long long cost_time = a8::XGetTickCount() - req->add_tick;
#ifdef DEBUG
a8::UdpLog::Instance()->Debug("ProxyHttpGet ok cost_time:%d url:%s params:%s",
{
cost_time,
req->url,
req->url_params.ToJsonStr(),
});
#endif
}
},
[] (a8::XParams& param, const std::string& response)
{
HttpProxyRequest* req = HttpProxy::Instance()->GetRequest(param.sender.GetString());
if (req) {
long long cost_time = a8::XGetTickCount() - req->add_tick;
a8::UdpLog::Instance()->Warning("ProxyHttpGet error cost_time:%d url:%s params:%s response:%s",
{
cost_time,
req->url,
req->url_params.ToJsonStr(),
response
});
req->on_error(req->param, response);
}
HttpProxy::Instance()->DestoryRequest(req);
},
proxy_url.c_str(),
*proxy_url_params,
rand() % MAX_SYS_HTTP_NUM
);
return request->req_id;
}
std::string HttpProxy::CreateRequestId()
{
return request_prefix_ + a8::XValue(App::Instance()->NewUuid()).GetString();
}
HttpProxyRequest* HttpProxy::GetRequest(const std::string& req_id)
{
auto itr = request_hash_.find(req_id);
return itr != request_hash_.end() ? itr->second : nullptr;
}
void HttpProxy::DestoryRequest(HttpProxyRequest* request)
{
request_hash_.erase(request->req_id);
delete request;
}