This commit is contained in:
2024-03-26 18:51:30 +08:00
parent 4a16d0a892
commit 87a37f4c5c
4 changed files with 118 additions and 9 deletions

View File

@@ -1,6 +1,6 @@
# Messenger SDK 开发文档 # Messenger SDK 开发文档
感谢的访问. 感谢的访问.
本站旨在为Messenger开发者提供清晰的入门资料. 本站旨在为Messenger开发者提供清晰的入门资料.
## 版权声明 ## 版权声明
@@ -25,10 +25,10 @@ SDK使用C++编写使用Messenger SDK需要一定的C++基础。
## 免责声明 ## 免责声明
本文档仅仅用来指导如何使用Messenger SDK我们对使用Messenger SDK进行的一切行为不承担任何责任 本文档仅仅用来指导如何使用Messenger SDK我们对使用Messenger SDK进行的一切行为不承担任何责任
由此导致的一切后果由自行承担。 由此导致的一切后果由自行承担。
如果您不能认可以上内容,请立即**关闭此文档**。 如果您不能认可以上内容,请立即**关闭此文档**。
打开本章节之后的内容,我们视为你已经认可了我们的免责声明。 打开本章节之后的内容,我们视为你已经认可了我们的免责声明。

View File

@@ -12,8 +12,8 @@ Messenger SDK一般是一个如下格式的压缩包
... ...
其中libs下放置的是一些静态连接库包含Android、Linux以及Windows。你需要将这些静态链接库链接到的项目中, 其中libs下放置的是一些静态连接库包含Android、Linux以及Windows。你需要将这些静态链接库链接到的项目中,
并且在项目的头文件搜索路径中添加 *include* 文件夹。 并且在项目的头文件搜索路径中添加 *include* 文件夹。
然后你将可以使用Messenger的API了。 然后你将可以使用Messenger的API了。
@@ -25,7 +25,7 @@ Messenger SDK的主要class是 ling::Messenger ,它提供了服务器全部API
> ling::Messenger以及ling::Client都具有ling前缀在C++中,这叫命名空间(*namespace*)。SDK内全部的class都在ling命名空间下。 > ling::Messenger以及ling::Client都具有ling前缀在C++中,这叫命名空间(*namespace*)。SDK内全部的class都在ling命名空间下。
ling::Messenger将是接触最多的class。 ling::Messenger将是接触最多的class。
它有两个构造函数: 它有两个构造函数:
~~~cpp ~~~cpp
@@ -91,3 +91,112 @@ int main(void){
~~~ ~~~
得到**ling::Messenger**的实例之后你可以通过它来调用Messenger的API。
例如,像这样来向服务器内注册当前设备。
~~~ cpp
#include <filesystem>
std::shared_ptr<ling::Messenger> api = ...
std::filesystem::path filePath = "/path/to/your/flag";
try{
if (!std::filesystem::exists(filePath)) {
::api->createDevice([](std::shared_ptr<ServerDataSuper> data)->void{
//此处的代码将会在服务器响应createDevice时被执行
if(data->isSuccess()){
//注册设备成功,则在磁盘上留下一个标记,下次启动时不再注册
std::ofstream outputFile(filePath);
outputFile.close();
//然后可以调用其他api了。
} else {
//服务器拒绝注册请求,可能是因为一些异常问题导致的,一般不会出现。
//为了程序健壮性,此处需要记录日志,这里仅仅打印一下。
std::cout << data->getMessage() << std::endl;
}
});
}
} catch (const ling::SendException & e){
//所有需要和服务器交换数据的api都会在网络断开时抛出此异常
//具体信息请查看异常处理一节。
//有无需捕获异常的优雅方法,将在后续章节中介绍。
}
~~~
### 发生了什么?
上面的代码可以简化成如下这样
~~~ cpp
::api->createDevice([](std::shared_ptr<ServerDataSuper> data)->void{
});
~~~
简单来说就是调用了全局命名空间中api对象的createDevice成员方法并将一个lambda表达式作为参数传递给了它。
lambda即匿名函数(*Anonymous Function*)。
查看createDevice方法的定义
~~~ cpp
void createDevice(const std::function<void(std::shared_ptr<ServerDataSuper>)> &call);
~~~
可以看到它需要一个**std::function**类型的参数。**std::function**是C++可调用对象的包装,它可以是一个具名函数
一个lambda表达式也可以是一个class的成员方法一个仿函数等等。一切可调用对象都可以使用**std::function**来包装。
参数中紧跟在**std::function**后面的 **<void(std::shared_ptr<ServerDataSuper>>)>** 是这个**std::function**的模板参数,
表示此**std::function**包装的可调用对象没有返回值,并且只需要一个 **std::shared_ptr<ServerDataSuper>** 类型的参数。
前面已经介绍过**std::shared_ptr**了,它同样是一个模板类型,尖括号中的**ServerDataSuper**是此智能指针管理对象的指针。
**ServerDataSuper**是Messenger服务器响应数据的封装类型是所有响应数据的基类。换句话说
,所有包装服务器响应数据的类型,都**直接或间接**的派生自**ServerDataSuper**。
例如,如下是服务器对登陆账号请求的响应信息包装类型的声明
~~~ cpp
namespace ling {
class LoginUserData : public ServerDataSuper {
};
}
~~~
可以看到它直接从ServerDataSuper派生这意味着你可以在任何服务器响应类型中调用ServerDataSuper中的方法它们是公共的。
对ServerDataSuper的介绍将在后续章节继续。
回到createDevice。
将上述简化代码继续简化,可以变成下面的样子。
~~~ cpp
/// 这段代码和上面简化后的代码是等价的!
void createDeviceResponse(std::shared_ptr<ServerDataSuper> data){
//等到服务器响应后Messenger才会调用这个函数。
//注意Messenger将在单独的线程中调用此函数
//Messenger将采取一定的策略管理线程无论如何你都不应该在此类回调函数中执行需要消耗大量时间的操作。
}
::api->createDevice(createDeviceResponse);
//调用后将会立即返回,继续向下执行
~~~
createDeviceResponse的定义**等价与**上面代码中的lambda表达式。
Messenger SDK的API是同服务器异步通信的也就是说createDevice会立即返回并继续向下执行。
等服务器响应createDevice时Messenger SDK将会调用参数中传递进去的可调用对象
在这里是createDeviceResponse并构造ServerDataSuper对象作为参数。
> 这都是C++的基础语法。请百度 回调函数(*callback*)

View File

@@ -14,7 +14,7 @@
<div id="app"></div> <div id="app"></div>
<script> <script>
window.$docsify = { window.$docsify = {
name: 'Messenger SDK 使用文档', name: 'Messenger 使用文档',
repo: '', repo: '',
mergeNavbar: true, mergeNavbar: true,
loadSidebar: 'list.md', loadSidebar: 'list.md',

View File

@@ -1,4 +1,4 @@
* 文档 * 开发文档
* [首页](README.md) * [首页](README.md)
* [快速入门](doc/entry.md) * [快速入门](doc/entry.md)
* [异常处理](doc/error.md) * [异常处理](doc/error.md)