客户端基础使用说明
更新时间:
1. 服务代码框架
代码框架包含一个 cpp 文件和一个 Makefie 文件。
假设要开发的客户端名字为 DemoClient,建立文件夹 DemoClient。
假设要访问的目标服务器为 demo.example.com,端口为 6789。
新建 cpp 文件 DemoClient.cpp 如下:
#include "TCPClient.h"
using namespace fpnn;
int main()
{
std::shared_ptr<TCPClient> client = TCPClient::createClient("demo.example.com", 6789);
return 0;
}
假设 FPNN-Release 的目录为 infra-fpnn-release-path,新建文件 Makefile 如下:
EXES_CLIENT = DemoClient
FPNN_DIR = infra-fpnn-release-path
CFLAGS +=
CXXFLAGS +=
CPPFLAGS += -I$(FPNN_DIR)/extends -I$(FPNN_DIR)/core -I$(FPNN_DIR)/proto -I$(FPNN_DIR)/base -I$(FPNN_DIR)/proto/msgpack -I$(FPNN_DIR)/proto/rapidjson
LIBS += -L$(FPNN_DIR)/extends -L$(FPNN_DIR)/core -L$(FPNN_DIR)/proto -L$(FPNN_DIR)/base -lextends -lfpnn
OBJS_CLIENT = DemoClient.o
all: $(EXES_CLIENT)
clean:
$(RM) *.o $(EXES_CLIENT)
include $(FPNN_DIR)/def.mk
2. 发送请求
发送请求有三个接口
class TCPClient
{
public:
/**
All SendQuest():
If return false, caller must free quest & callback.
If return true, don't free quest & callback.
timeout in seconds.
*/
FPAnswerPtr sendQuest(FPQuestPtr quest, int timeout = 0);
bool sendQuest(FPQuestPtr quest, AnswerCallback* callback, int timeout = 0);
bool sendQuest(FPQuestPtr quest, std::function<void (FPAnswerPtr answer, int errorCode)> task, int timeout = 0);
... ...
};
其中返回类型为 FPAnswerPtr 的接口,有可能抛出异常,而且返回的 FPAnswerPtr 根据情况不同,可能为 nullptr (比如发送 oneway 类型的请求)。
其余两个返回 bool 类型的接口不会抛出异常。
假设要访问的接口为 twoway 类型,接口名称为 echo,参数为一个字符串类型,参数名为 feedback。
以 FPAnswerPtr sendQuest() 为例,修改 DemoClient.cpp 代码如下:
#include <iostream>
#include "TCPClient.h"
using namespace std;
using namespace fpnn;
int main()
{
std::shared_ptr<TCPClient> client = TCPClient::createClient("demo.example.com", 6789);
//-- 生成请求数据
FPQWriter qw(1, "echo");
qw.param("feedback", "Example string.");
try{
FPAnswerPtr answer = client->sendQuest(qw.take());
}
catch (const FpnnError& ex)
{
cout<<"Fpnn error. code: "<<ex.code()<<", msg: "<<ex.what()<<endl;
}
catch (...)
{
cout<<"error occurred when sending"<<endl;
}
return 0;
}
其中:
- FPQWriter 是 FPQuest 的生成器。需要将最表层的参数个数,和要访问的接口名称作为参数传入。
- qw.param() 函数将自动识别参数类型。
- take() 操作,将会自动生成 FPQuestPtr 对象。
- 一个 FPQWriter 对象,只能 take() 一次。
具体请参见:/proto/FPWriter.h。
更多实例请参见 /proto/test/。
3. 解析请求结果
假设上文访问的 echo 接口有一个字符串类型的返回参数,参数名为 got,则可以用 FPAReader 获取参数。
修改 DemoClient.cpp 代码如下:
#include <iostream>
#include "TCPClient.h"
using namespace std;
using namespace fpnn;
int main()
{
std::shared_ptr<TCPClient> client = TCPClient::createClient("demo.example.com", 6789);
FPQWriter qw(1, "echo");
qw.param("feedback", "Example string.");
try{
FPAnswerPtr answer = client->sendQuest(qw.take());
FPAReader ar(answer);
std::string got = ar.wantString("got");
cout<<"Server return data: "<<got<<endl;
}
catch (const FpnnError& ex)
{
cout<<"Fpnn error. code: "<<ex.code()<<", msg: "<<ex.what()<<endl;
}
catch (...)
{
cout<<"error occurred when sending"<<endl;
}
return 0;
}
FPAReader 需要用有效的 FPAnswerPtr 对象初始化。然后就可以用 wantXXX() 和 getXXX() 通过参数名,获取对应的参数。
比如,要获取一个名为 paramInt 的整型参数(int64_t, int32_t, int, int16_t, int8_t, …),可以使用
int a = ar.wantInt("paramInt")
//-- or
int a = ar.getInt("paramInt")
对于字符串,假设参数名为 paramString
std::string str = ar.wantString("paramString")
//-- or
std::string str = ar.getString("paramString")
对于数组,假设参数名为 IntArray 和 StringArray
std::vector<int> arr = ar.want("IntArray", std::vector<int>())
std::vector<std::string> arr = ar.want("IntArray", std::vector<std::string>())
//-- or
std::vector<int> arr = ar.get("IntArray", std::vector<int>())
std::vector<std::string> arr = ar.get("IntArray", std::vector<std::string>())
更多更详细的接口,请参见:/proto/FPReader.h。
更多实例请参见 /proto/test/。
至于使用 want 还是 get,取决于要获取的参数,是否是可选参数。
want 系列方法,要求参数必须存在,且类型匹配。否则会抛出异常。
对于客户端,需要开发者捕获,并处理异常。
对于 get 系列方法,对应于可选参数。不要求参数必须存在。如果目标参数不存在,则返回默认值。
默认值可以指定,比如:
int a = ar.getInt("paramInt", 100)
std::string str = ar.getString("paramString", "default")
get 系列接口的默认值如下:
类型
默认值
整型
0
浮点型
0.0
bool
false
字符串
""
具体请参见:/proto/FPReader.h。
更多实例请参见 /proto/test/。
以上即为客户端全部完整代码。
1. 服务代码框架
代码框架包含一个 cpp 文件和一个 Makefie 文件。
假设要开发的客户端名字为 DemoClient,建立文件夹 DemoClient。
假设要访问的目标服务器为 demo.example.com,端口为 6789。
新建 cpp 文件 DemoClient.cpp 如下:
#include "TCPClient.h"
using namespace fpnn;
int main()
{
std::shared_ptr<TCPClient> client = TCPClient::createClient("demo.example.com", 6789);
return 0;
}
假设 FPNN-Release 的目录为 infra-fpnn-release-path,新建文件 Makefile 如下:
EXES_CLIENT = DemoClient
FPNN_DIR = infra-fpnn-release-path
CFLAGS +=
CXXFLAGS +=
CPPFLAGS += -I$(FPNN_DIR)/extends -I$(FPNN_DIR)/core -I$(FPNN_DIR)/proto -I$(FPNN_DIR)/base -I$(FPNN_DIR)/proto/msgpack -I$(FPNN_DIR)/proto/rapidjson
LIBS += -L$(FPNN_DIR)/extends -L$(FPNN_DIR)/core -L$(FPNN_DIR)/proto -L$(FPNN_DIR)/base -lextends -lfpnn
OBJS_CLIENT = DemoClient.o
all: $(EXES_CLIENT)
clean:
$(RM) *.o $(EXES_CLIENT)
include $(FPNN_DIR)/def.mk
2. 发送请求
发送请求有三个接口
class TCPClient
{
public:
/**
All SendQuest():
If return false, caller must free quest & callback.
If return true, don't free quest & callback.
timeout in seconds.
*/
FPAnswerPtr sendQuest(FPQuestPtr quest, int timeout = 0);
bool sendQuest(FPQuestPtr quest, AnswerCallback* callback, int timeout = 0);
bool sendQuest(FPQuestPtr quest, std::function<void (FPAnswerPtr answer, int errorCode)> task, int timeout = 0);
... ...
};
其中返回类型为 FPAnswerPtr 的接口,有可能抛出异常,而且返回的 FPAnswerPtr 根据情况不同,可能为 nullptr (比如发送 oneway 类型的请求)。
其余两个返回 bool 类型的接口不会抛出异常。
假设要访问的接口为 twoway 类型,接口名称为 echo,参数为一个字符串类型,参数名为 feedback。
以 FPAnswerPtr sendQuest() 为例,修改 DemoClient.cpp 代码如下:
#include <iostream>
#include "TCPClient.h"
using namespace std;
using namespace fpnn;
int main()
{
std::shared_ptr<TCPClient> client = TCPClient::createClient("demo.example.com", 6789);
//-- 生成请求数据
FPQWriter qw(1, "echo");
qw.param("feedback", "Example string.");
try{
FPAnswerPtr answer = client->sendQuest(qw.take());
}
catch (const FpnnError& ex)
{
cout<<"Fpnn error. code: "<<ex.code()<<", msg: "<<ex.what()<<endl;
}
catch (...)
{
cout<<"error occurred when sending"<<endl;
}
return 0;
}
其中:
- FPQWriter 是 FPQuest 的生成器。需要将最表层的参数个数,和要访问的接口名称作为参数传入。
- qw.param() 函数将自动识别参数类型。
- take() 操作,将会自动生成 FPQuestPtr 对象。
- 一个 FPQWriter 对象,只能 take() 一次。
具体请参见:
更多实例请参见
3. 解析请求结果
假设上文访问的 echo 接口有一个字符串类型的返回参数,参数名为 got,则可以用 FPAReader 获取参数。 修改 DemoClient.cpp 代码如下:
#include <iostream>
#include "TCPClient.h"
using namespace std;
using namespace fpnn;
int main()
{
std::shared_ptr<TCPClient> client = TCPClient::createClient("demo.example.com", 6789);
FPQWriter qw(1, "echo");
qw.param("feedback", "Example string.");
try{
FPAnswerPtr answer = client->sendQuest(qw.take());
FPAReader ar(answer);
std::string got = ar.wantString("got");
cout<<"Server return data: "<<got<<endl;
}
catch (const FpnnError& ex)
{
cout<<"Fpnn error. code: "<<ex.code()<<", msg: "<<ex.what()<<endl;
}
catch (...)
{
cout<<"error occurred when sending"<<endl;
}
return 0;
}
FPAReader 需要用有效的 FPAnswerPtr 对象初始化。然后就可以用 wantXXX() 和 getXXX() 通过参数名,获取对应的参数。
比如,要获取一个名为 paramInt 的整型参数(int64_t, int32_t, int, int16_t, int8_t, …),可以使用
int a = ar.wantInt("paramInt")
//-- or
int a = ar.getInt("paramInt")
对于字符串,假设参数名为 paramString
std::string str = ar.wantString("paramString")
//-- or
std::string str = ar.getString("paramString")
对于数组,假设参数名为 IntArray 和 StringArray
std::vector<int> arr = ar.want("IntArray", std::vector<int>())
std::vector<std::string> arr = ar.want("IntArray", std::vector<std::string>())
//-- or
std::vector<int> arr = ar.get("IntArray", std::vector<int>())
std::vector<std::string> arr = ar.get("IntArray", std::vector<std::string>())
更多更详细的接口,请参见:
更多实例请参见
至于使用 want 还是 get,取决于要获取的参数,是否是可选参数。
want 系列方法,要求参数必须存在,且类型匹配。否则会抛出异常。
对于客户端,需要开发者捕获,并处理异常。
对于 get 系列方法,对应于可选参数。不要求参数必须存在。如果目标参数不存在,则返回默认值。
默认值可以指定,比如:
int a = ar.getInt("paramInt", 100)
std::string str = ar.getString("paramString", "default")
get 系列接口的默认值如下:
类型 | 默认值 |
---|---|
整型 | 0 |
浮点型 | 0.0 |
bool | false |
字符串 | "" |
具体请参见:
更多实例请参见
以上即为客户端全部完整代码。