182 lines
5.7 KiB
C++
182 lines
5.7 KiB
C++
#include "precompile.h"
|
|
|
|
#include <a8/sysutils.h>
|
|
#include <a8/mutable_xobject.h>
|
|
#include <a8/awaiter.h>
|
|
#include <a8/promise.h>
|
|
|
|
#include <f8/udplog.h>
|
|
#include <f8/jsonhttprequest.h>
|
|
|
|
#include "httpproxy.h"
|
|
#include "app.h"
|
|
#include "jsondatamgr.h"
|
|
#include "handlermgr.h"
|
|
|
|
#include "f8/httpclientpool.h"
|
|
|
|
struct HttpProxyRequest
|
|
{
|
|
std::string req_id;
|
|
f8::HttpProxyCb cb;
|
|
std::string url;
|
|
a8::XObject url_params;
|
|
long long add_tick = 0;
|
|
};
|
|
|
|
class HttpProxyPromise : public a8::Promise
|
|
{
|
|
public:
|
|
|
|
HttpProxyPromise(const char* url, a8::XObject url_params)
|
|
{
|
|
url_ = url;
|
|
url_params_ = url_params;
|
|
}
|
|
|
|
protected:
|
|
|
|
virtual void DoAwait() override
|
|
{
|
|
HttpProxy::Instance()->HttpGet
|
|
(
|
|
[this, _self = shared_from_this()]
|
|
(bool ret, a8::XObject* xobj, f8::HttpContext* context)
|
|
{
|
|
std::shared_ptr<a8::XObject> data = std::make_shared<a8::XObject>();
|
|
*data = *xobj;
|
|
SetResult({ret, data});
|
|
DoDone();
|
|
},
|
|
url_.c_str(),
|
|
url_params_);
|
|
}
|
|
|
|
private:
|
|
std::string url_;
|
|
a8::XObject url_params_;
|
|
};
|
|
|
|
static void _ProxyCallback(std::shared_ptr<f8::JsonHttpRequest> request)
|
|
{
|
|
#ifdef DEBUG
|
|
f8::UdpLog::Instance()->Debug("ProxyCallbBack request:%s",
|
|
{
|
|
request->params->ToJsonStr()
|
|
});
|
|
#endif
|
|
std::string seq_id = request->params->Get("seq_id");
|
|
std::shared_ptr<HttpProxyRequest> req = HttpProxy::Instance()->GetRequest(seq_id);
|
|
if (req) {
|
|
a8::XObject data;
|
|
|
|
data.ReadFromJsonString(request->params->Get("data").GetString());
|
|
if (data.GetType() == a8::XOT_SIMPLE) {
|
|
data.ReadFromJsonString("{}");
|
|
}
|
|
f8::HttpContext ctx;
|
|
if (request->params->HasKey("errcode") &&
|
|
request->params->Get("errcode").GetInt() == 0) {
|
|
req->cb(true, &data, &ctx);
|
|
} else {
|
|
req->cb(false, request->params.get(), &ctx);
|
|
}
|
|
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(
|
|
f8::HttpProxyCb cb,
|
|
const char* url,
|
|
a8::XObject url_params
|
|
)
|
|
{
|
|
std::shared_ptr<HttpProxyRequest> request = std::make_shared<HttpProxyRequest>();
|
|
request->req_id = CreateRequestId();
|
|
request->cb = cb;
|
|
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
|
|
(
|
|
[request] (bool ok, a8::XObject* rsp_obj, f8::HttpContext* ctx)
|
|
{
|
|
long long cost_time = a8::XGetTickCount() - request->add_tick;
|
|
if (ok) {
|
|
#ifdef DEBUG
|
|
f8::UdpLog::Instance()->Debug("ProxyHttpGet ok cost_time:%d url:%s params:%s",
|
|
{
|
|
cost_time,
|
|
request->url,
|
|
request->url_params.ToJsonStr(),
|
|
});
|
|
#endif
|
|
} else {
|
|
f8::UdpLog::Instance()->Warning("ProxyHttpGet error cost_time:%d url:%s params:%s response:%s",
|
|
{
|
|
cost_time,
|
|
request->url,
|
|
request->url_params.ToJsonStr(),
|
|
ctx->response
|
|
});
|
|
request->cb(false, rsp_obj, ctx);
|
|
HttpProxy::Instance()->DestoryRequest(request);
|
|
}
|
|
},
|
|
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();
|
|
}
|
|
|
|
std::shared_ptr<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(std::shared_ptr<HttpProxyRequest> request)
|
|
{
|
|
request_hash_.erase(request->req_id);
|
|
}
|
|
|
|
std::shared_ptr<a8::Awaiter> HttpProxy::CoHttpGet(const char* url,
|
|
a8::XObject url_params)
|
|
{
|
|
return std::make_shared<HttpProxyPromise>(url, url_params);
|
|
}
|