- 分享一种不太完美的接入网关设计
- 来源:腾讯大讲堂
switch (cmd)
{
case HEAD: new head;
case REQ: new req;
}
{
"args": {
"req": {
"hospitalId": "10056"
},
"head": {
"requestId": "ooJQ346G2CMqcSujAt8yE8-Stutc",
"openId": "ooJQ346G2CMqcSujAt8yE8-Stutc"
}
},
"service": "TencentHealthRegister",
"func": "getHospitalInfo",
"context": {
"requestId": "b9bf3541-3753-11e9-8213-e5de4f5e7b53",
"traceId": "b9bf3540-3753-11e9-8213-e5de4f5e7b53"
}
}
module TencentHealthMini {
struct ThHead{
0 optional string requestId;
1 require string openId;
2 optional string channel;
3 optional string cityCode;
};
struct HospitalReq{
0 require string hospitalId;
1 optional string platformId;
};
struct HospitalRsp{
0 require Result result;
1 require HospitalInfo hospitalInfo;
};
interface ThRegisterMain {
int getHospitalInfo(ThHead head,HospitalReq req, out HospitalRsp rsp);
}
}
head = ThHead
req = HospitalReq
rsp = HospitalRsp
</getHospitalInfo>
template<typename Base>
class ObjGen
{
public:
virtual Base* operator()()
{
return NULL;
}
};
template<typename Base>
std::map<std::string, ObjGen * >& GetObjMap()
{
static std::map<std::string, ObjGen * > obj_map;
return obj_map;
}
#define REGISTER_CLASS(BASE_NAMESPACE, BASE_NAME, CLASS_NAMESPACE, CLASS_NAME)\
class Gen##CLASS_NAMESPACE##CLASS_NAME: public GenObjectFun \
{\
public:\
BASE_NAMESPACE::BASE_NAME* operator()()\
{\
return new CLASS_NAMESPACE::CLASS_NAME;\
}\
};\
\
static struct CLASS_NAMESPACE##CLASS_NAME##AutoInit\
{\
CLASS_NAMESPACE##CLASS_NAME##AutoInit()\
{\
if(GetObjMap().find(#CLASS_NAMESPACE"."#CLASS_NAME) == GetObjMap ().end())\
GetObjMap().insert(std::make_pair(#CLASS_NAMESPACE"."#CLASS_NAME, new Gen##CLASS_NAMESPACE##CLASS_NAME));\
}\
}__##CLASS_NAMESPACE##CLASS_NAME##AutoInit;
template <typename Base>
Base* GetObject(const std::string& class_name){
typename std::map<std::string, ObjGen * >::const_iterator iter = GetObjMap ().find(class_name);
if(iter == GetObjMap ().end())
{
return NULL;
}
return (*iter->second)();
}
struct HospitalReq : public taf::JceStructBase
{
public:
static string className()
{
return "TencentHealthMini.HospitalReq";
}
static string MD5()
{
return "325d87d477a8cf7a6468ed6bb39da964";
}
......
}
namespace taf
{
//////////////////////////////////////////////////////////////////
struct JceStructBase
{
protected:
JceStructBase() {}
~JceStructBase() {}
};
struct JceException : public std::runtime_error
{
JceException(const std::string& s) : std::runtime_error(s) {}
};
struct JceEncodeException : public JceException
{
JceEncodeException(const std::string& s) : JceException(s) {}
};
struct JceDecodeException : public JceException
{
JceDecodeException(const std::string& s) : JceException(s) {}
};
......
}
namespace THComm
{
//////////////////////////////////////////////////////////////////
struct JceStructBase:public taf::JceStructBase
{
public:
JceStructBase() {}
virtual ~JceStructBase() {}
virtual void writeTo(taf::JceOutputStream& _os, UInt8 tag) const
{
LOG_ERROR("not supported");
throw new std::runtime_error("not supported.");
}
virtual void writeToJson(rapidjson::Value& _jVal, rapidjson::Document::AllocatorType& _jAlloc) const
{
LOG_ERROR("not supported");
throw new std::runtime_error("not supported.");
}
virtual std::string writeToJsonString()
{
LOG_ERROR("not supported");
throw new std::runtime_error("not supported.");
}
virtual std::string writeToJsonStringV2() const
{
LOG_ERROR("not supported");
throw new std::runtime_error("not supported.");
}
virtual void readFrom(taf::JceInputStream& _is, UInt8 tag)
{
LOG_ERROR("not supported");
throw new std::runtime_error("not supported.");
}
virtual void readFromJson(const rapidjson::Value& _jVal, bool isRequire = true)
{
LOG_ERROR("not supported");
throw new std::runtime_error("not supported.");
}
virtual void readFromJsonString(const std::string & str)
{
LOG_ERROR("not supported");
throw new std::runtime_error("not supported.");
}
virtual void readFromJsonStringV2(const std::string & str)
{
LOG_ERROR("not supported");
throw new std::runtime_error("not supported.");
}
virtual void writeToString(std::string &content;)
{
LOG_ERROR("not supported");
throw new std::runtime_error("not supported.");
}
virtual void readFromString(const std::string & str)
{
LOG_ERROR("not supported");
throw new std::runtime_error("not supported.");
}
virtual ostream& display(ostream& _os, int _level=0) const
{
LOG_ERROR("not supported");
throw new std::runtime_error("not supported.");
}
virtual ostream& displaySimple(ostream& _os, int _level=0) const
{
LOG_ERROR("not supported");
throw new std::runtime_error("not supported.");
}
};
}
struct HospitalReq : public THComm::JceStructBase
{
public:
static string className()
{
return "TencentHealthMini.HospitalReq";
}
static string MD5()
{
return "325d87d477a8cf7a6468ed6bb39da964";
}
......
}
#include "ThRegisterMain.h"
#include "jce/wup.h"
#include "servant/BaseF.h"
using namespace wup;
namespace TencentHealthMini
{
REGISTER_CLASS(THComm, JceStructBase, TencentHealthMini, HospitalReq)
REGISTER_CLASS(THComm, JceStructBase, TencentHealthMini, HospitalRsp)
REGISTER_CLASS(THComm, JceStructBase, TencentHealthMini, PayAppointReq)
REGISTER_CLASS(THComm, JceStructBase, TencentHealthMini, PayAppointRsp)
REGISTER_CLASS(THComm, JceStructBase, TencentHealthMini, ScheduleReq)
REGISTER_CLASS(THComm, JceStructBase, TencentHealthMini, ScheduleRsp)
REGISTER_CLASS(THComm, JceStructBase, TencentHealthMini, SourceReq)
......
}
map<string, string>& GetParameterTypeMap()
{
static map<string, string> parameter_type_map;
return parameter_type_map;
}
#define REGISTER_PARAMETER(CLASS_NAMESPACE, INTERFACE_CLASS, FUNC, PARAMETER, PARAMETER_TYPE, OUT)\
static struct CLASS_NAMESPACE##INTERFACE_CLASS##FUNC##PARAMETER##Initializer\
{\
CLASS_NAMESPACE##INTERFACE_CLASS##FUNC##PARAMETER##Initializer()\
{\
if (GetParameterTypeMap().find(PARAMETER_INDEX(CLASS_NAMESPACE, INTERFACE_CLASS, FUNC, PARAMETER)) == GetParameterTypeMap().end())\
GetParameterTypeMap().insert(make_pair(PARAMETER_INDEX(CLASS_NAMESPACE, INTERFACE_CLASS, FUNC, PARAMETER), #PARAMETER_TYPE));\
\
if (!OUT)\
{\
map >::iterator iter = GetParameterSequenceMap().find(FUNC_INDEX(CLASS_NAMESPACE, INTERFACE_CLASS, FUNC));\
if (iter == GetParameterSequenceMap().end())\
{\
vector parameterSequence;\
parameterSequence.push_back(#PARAMETER);\
GetParameterSequenceMap().insert(make_pair(FUNC_INDEX(CLASS_NAMESPACE, INTERFACE_CLASS, FUNC), parameterSequence));\
}\
else\
{\
vector& parameterSequence = iter->second;\
parameterSequence.push_back(#PARAMETER);\
}\
}\
else \
{\
map >::iterator iter = GetOutParameterSequenceMap().find(FUNC_INDEX(CLASS_NAMESPACE, INTERFACE_CLASS, FUNC));\
if (iter == GetOutParameterSequenceMap().end())\
{\
vector outParameterSequence;\
outParameterSequence.push_back(#PARAMETER);\
GetOutParameterSequenceMap().insert(make_pair(FUNC_INDEX(CLASS_NAMESPACE, INTERFACE_CLASS, FUNC), outParameterSequence));\
}\
else\
{\
vector& outParameterSequence = iter->second;\
outParameterSequence.push_back(#PARAMETER);\
}\
}\
}\
}__##CLASS_NAMESPACE##INTERFACE_CLASS##FUNC##PARAMETER##Initializer;
//获取参数类型
void PrintParameterTypeMap();
map& GetParameterTypeMap();
string GetParameterType(const string& CLASS_NAMESPACE, const string& INTERFACE_CLASS, const string& FUNC, const string& PARAMETER);
//获取入参顺序
void PrintParameterSequence();
map<string, vector<std::string> >& GetParameterSequenceMap();
vector<string> GetParameterSequence(const string& CLASS_NAMESPACE, const string& INTERFACE_CLASS, const string& FUNC);
//出参顺序
void PrintOutParameterSequence();
map<string, vector<string> >& GetOutParameterSequenceMap();
vector<string> GetOutParameterSequence(const string& CLASS_NAMESPACE, const string& INTERFACE_CLASS, const string& FUNC);
map<string, vector<string> >& GetParameterSequenceMap()
{
static map<string, vector<string> > parameter_sequence_map;
return parameter_sequence_map;
}
map<string, vector<string> >& GetOutParameterSequenceMap()
{
static map<string, vector<string> > out_parameter_sequence_map;
return out_parameter_sequence_map;
}
#include "ThRegisterMain.h"
#include "jce/wup.h"
#include "servant/BaseF.h"
using namespace wup;
namespace TencentHealthMini
{
REGISTER_CLASS(THComm, JceStructBase, TencentHealthMini, HospitalReq)
REGISTER_CLASS(THComm, JceStructBase, TencentHealthMini, HospitalRsp)
......
REGISTER_PARAMETER(TencentHealthMini, ThRegisterMain, getHospitalInfo, head, TencentHealthMini::ThHead, 0)
REGISTER_PARAMETER(TencentHealthMini, ThRegisterMain, getHospitalInfo, req, TencentHealthMini::HospitalReq, 0)
REGISTER_PARAMETER(TencentHealthMini, ThRegisterMain, getHospitalInfo, rsp, TencentHealthMini::HospitalRsp, 1)
......
}
bool httpImp::tafAsyncCall(HttpRequestPtr httpReq)
{
RequestInfo& reqInfo = httpReq->reqInfo;
taf::JceOutputStream os;
for (size_t i = 0; i < reqInfo.argsSequence.size(); i++)
{
string& argName = reqInfo.argsSequence[i];
Arg& arg = reqInfo.args[argName];
if (NULL == arg._pJceStr)
{
LOG_ERROR(httpReq->requestId << ",argName:" << argName << ",jce struct is null");
return false;
}
arg._pJceStr->readFromJsonStringV2(arg.data);
arg._pJceStr->writeTo(os, i+1);
}
......
}
......
CommCallbackPtr callback = new CommCallback;
callback->httpReq = httpReq;
map::iterator iter = g_app._proxyMap.find(reqInfo.service);
LOG_DEBUG(httpReq->requestId << ",THProxyServer costime:" << TNOWMS - httpReq->acceptReqTime);
if (iter != g_app._proxyMap.end())
{
LOG_DEBUG(httpReq->requestId
<< ",service:" << reqInfo.service
<< ",func:" << reqInfo.func
<< "," << reqInfo.reqStr
<< ",context:" << contextStr);
taf::ServantPrx proxy = iter->second;
proxy->taf_invoke_async(taf::JCENORMAL, reqInfo.func, os.getByteBuffer(), context, mStatus, callback);
}
else
{
LOG_ERROR(httpReq->requestId << ",service:" << reqInfo.service << ",");
return false;
}
class CommCallback: public taf::ServantProxyCallback
{
public:
virtual ~CommCallback(){}
void done()
{
}
void exception(taf::Int32 ret)
{
LOG_ERROR("ret:" << ret);
}
int procResponse(taf::ReqMessagePtr msg ,taf::JceInputStream& is, int ret);
virtual int onDispatch(taf::ReqMessagePtr msg);
HttpRequestPtr httpReq;
};
typedef TC_AutoPtr CommCallbackPtr;
其他
-
- 5G的变革能力被普遍低估, 但没人可以置身事外
- 如果生态参与者忽视了5G带来的一系列变革,仅仅选择简单跟随,未能以变御变,那么失去的将可能是一个时代 余进 孙岳 | 文 移动通信大会上的5G+远程驾驶体验区。图/视觉中国 5G来临,绝不仅仅是网
- 财经十一人
-
- 奶茶煮饭?奶茶酸辣粉?奶茶炖蛋?所以,奶茶做错了什么!?
- 首先我们先请出今天的主角 把不需要搭配奶茶的珍珠分离开 为了大大提高匹配度 在最近一些火爆的奶茶料理启发下 兔子精心邀请了这次的主要 “相亲对象” 来看看你站哪对CP?! ▽▽▽ 糯米先生
- 重庆吃货王
-
- 物联网的过去、现在和未来
- 一瓶肥宅快乐水引发的技术革命,让我们渐渐离不开物联网。 10年前有一本书预测了如今的生活在物联网技术下的样子,现在又有产业大咖预测物联网十年后的样子。这20年的跨度,对物联网来说到底有什么区别?
- TechSugar
-
- 《水下的无无先生》第二季第十九节
- 准备回家,果然又遇到痞子。 上次是三个,这次是两个,上次站在中间比较帅的那个,这次还在其中。 哑巴! 比较帅的那个又开始叫了起来。 无无先生把车停下,还没有任何动作,我已经迎到前面,掏出早已买
- 王泡小泡
-
- 【砚田书院】 一半,一半
- 一半,一半。 转眼间,2019已快过完一半! 一半是回忆,一半是继续。 不乱于心,不困于情。 心情不好的时候, 只想一个人安安静静的待着, 不求安慰,只求有个人能懂。 没有不老的时光, 没有永远
- 砚田书院
-
- 分享一种不太完美的接入网关设计
- 作者:朱江,腾讯工程师。 写在前面: 如上图所示,客户端通过HTTP+JSON协议请求ProxyServer,由其派发到后端不同服务的不同接口处理,从而获取结果。那么ProxyServer需要具备怎
- 腾讯大讲堂
-
- 无人机在水土保持工作中的应用
- 本期期刊速读内容来自《科技风》杂志2019年8月的文章《无人机在水土保持工作中的应用》,作者党桐。 文章首先说明了无人机在水土保持工作中的重要优势,然后重点分析了无人机在水土保持工作中的应用,革新了
- 山泽研习社
-
- 社会广泛关注泛在电力物联网智能感知技术论坛
- 近日,以“全面智能感知,泛在电力物联”为主题的泛在电力物联网智能感知技术论坛在京举行。来自政府部门、社会团体、国家电网公司、南方电网公司及各省、地(市)电力公司、发电企业、电力科研机构、高等院校、国内
- 中国电力科学研究院
-
- 习练八段锦的注意事项(附真人动态图解)
- 语音版(预计11分13秒)普通话 - 来自漾太极 - / 11:13 经络不畅,则百病丛生。如何打通经络,气血十足呢?中医以气血为核心,特别以气为根本,八段锦则应运而生。 这种用来调理脏腑气血、恢
-
- 世界变坏,是从嘲笑项羽开始的
- 一旦发现关注不了“大公馆”的时候,请您请移步 “大公馆2013"(新的公众号:DGG-668)马上保持同步关注。 大公馆2013(新公众号:DGG-668)会在次日清晨发布,内容基本与旧大公馆的保持
- 大公馆
-
- 24年历经多个岗位磨练,一位出版社总编辑的成长史
- 文/柴小珊 本文约5100字,预计8分钟阅读完毕 商务君按:“70后”是亲眼见证了时代巨变的一代人,也是目前出版行业的中坚力量,他们如何与时代交集,又有着怎样的成长轨迹?商务君独家专访国防工业出版社
- 出版商务周报
-
- 世汉学会2019年暑期高级讲习班都讲了哪些干货?快来看看吧
- 孔子学院 用我们的语言讲述中国故事 关注 孔子学院 孔子学院 8月2日,来自全球207所高校263名青年教师和研究生应邀参加世界汉语教学学会2019年暑期高级讲习班,本期主题是“国际汉语教育教学与
- 孔子学院
-
- 煮排骨汤时加上它,一周后体内的湿毒都排净了,养生又美味
- 立秋后吃哪些食物对身体有益? 薏 米 转眼就立秋了,是到了“贴秋膘”的时候了。经历“苦夏”人们大多会瘦,而瘦了当要“补”。所以,所以才有这“贴秋膘”的说法。其实现如今生活好起了,大家更注意
- 小鹿厨房
-
- 半生拙于世,一笔一划成画痴
- 广平水陆画丨水陆画是一种传统宗教绘画,是佛、道、儒三教题材内容融合而成的一种艺术创作。其绘画题材离不开佛、道、儒三教的诸佛菩萨、各方神道、人间社会各色人物等,它既有描绘宗教世界的内容,也有反映世俗社会
- GUYU谷雨
-
- 民营银行年薪几何? 去年人均薪酬57万,超A股城商行近40%
- 每日经济新闻 自2014年首批5家民营银行获批筹建后,截至目前已有17家民营银行开业运营。其中,最早获批开业的前海微众银行即将在今年底满“5岁”,最晚取得开业批复的安徽新安银行也已经历了一年零八个月的
- 中国电子银行网
朋友会在“发现-看一看”看到你“在看”的内容