ECS_搭建个人Leanote云笔记本

本文档详细介绍了在Linux系统上安装MongoDB的过程,包括配置YUM源、安装服务及启动。接着,讲解了 Leanote云笔记的下载、安装、配置数据库以及安全设置。最后,演示了启动 Leanote 服务并访问云笔记的方法。

1.安装MongoDB

yum -y install mongodb mongodb-server.x86_64 mariadb-devel.i686

在这里插入图片描述
执行以下命令,启动MongoDB服务。

systemctl start mongod

启动失败
在这里插入图片描述

No package mongodb available.

在这里插入图片描述

配置MongoDB的yum源

cd /etc/yum.repos.d 

vim mongodb-org-4.0.repo 

这里可以修改 gpgcheck=0, 省去gpg验证

[mngodb-org]
name=MongoDB Repository
baseurl=http://mirrors.aliyun.com/mongodb/yum/redhat/7Server/mongodb-org/4.0/x86_64/
gpgcheck=0
enabled=1

安装之前先更新所有包 :

yum update

安装命令:

yum -y install mongodb-org

在这里插入图片描述

安装完成后

查看mongo安装位置 whereis mongod
在这里插入图片描述

查看修改配置文件 : vim /etc/mongod.conf

bindIp: 172.0.0.1 改为 bindIp: 0.0.0.0(注意冒号与ip之间需要一个空格)

在这里插入图片描述

启动mongodb :systemctl start mongod.service

查到mongodb的状态:systemctl status mongod.service
在这里插入图片描述

安装Leanote

下载Leanote二进制安装包。

wget https://nchc.dl.sourceforge.net/project/leanote-bin/2.6.1/leanote-linux-amd64-v2.6.1.bin.tar.gz

解压安装包。

tar -zxvf leanote-linux-amd64-v2.6.1.bin.tar.gz

编辑文件leanote/conf/app.conf,在文件中找到app.secret项,将该项的值改为任意字符串。(如不修改将会有安全风险)。

说明: 根据Leanote官方文档,如不修改app.secret项的值,将会有安全隐患。

在这里插入图片描述

a. 使用vim编辑器打开文件leanote/conf/app.conf。

vim leanote/conf/app.conf

b. 进入vim编辑器后,输入:/app.secret=并按下回车查找app.secret位置。

c. 找到该项位置后按下i键进入编辑模式,修改该项的值为任意字符串。

d. 修改完成后,按下esc键退出编辑模式,输入:wq保存并退出vim编辑器。
在这里插入图片描述

初始化数据库。

mongorestore -h localhost -d leanote --dir ~/leanote/mongodb_backup/leanote_install_data/

启动服务。

nohup bash leanote/bin/run.sh > leanote/run.log 2>&1 &

访问云笔记。

在浏览器中访问http://<ECS公网地址>:9000,请将<ECS公网地址>替换为左侧资源栏中的ECS公网IP地址。默认管理用户为admin,密码为abc123。登录成功后如下图所示。
在这里插入图片描述

<think> 我们被提供了一个函数指针类型和结构体的定义。用户要求设计上传报文的形式和通讯协议。之前的讨论中,我们已经设计了一个二进制报文的示例,并给出了回调函数的实现模板。现在,用户补充了具体的类型定义,我们可以根据这些定义进行调整。 根据补充的代码: - `ECS_RPT_FUNC` 是一个函数指针类型,它指向的函数接受三个参数:`ECS_SESS* pSess`, `ECS_s8* keyName`, 和 `JSON_Value **pOutVal`,返回`ECS_s32`(可能是错误码)。 - `ECS_RPT_FUNC_NODE` 结构体中包含了注册报告函数所需的信息,其中`func`就是上述函数指针。 值得注意的是,在回调函数中,有一个`OUT JSON_Value **pOutVal`参数,这意味着回调函数需要构建一个JSON格式的数据,并通过这个参数输出。因此,我们之前设计的二进制报文可能需要调整,因为这里似乎要求使用JSON格式。 ### 调整方案: 1. **报文格式**:由于回调函数要求输出JSON,我们应该设计一个JSON格式的上报报文。 2. **回调函数实现**:在回调函数中,我们需要创建一个`JSON_Value`对象,然后将其赋值给`*pOutVal`。 3. **通讯协议**:由于数据已经是JSON格式,我们可以选择HTTP或者MQTT等应用层协议,这些协议通常与JSON配合较好。 ### 修改后的上报报文设计(JSON格式): 假设计数数据包括设备ID、时间戳、序列号和计数值,我们可以设计如下的JSON结构: ```json { "device_id": "DEV12345", "timestamp": 1672531200000, "sequence": 123, "counter_value": 4567 } ``` ### 修改后的回调函数实现模板: ```c ECS_s32 counterReportFunc(IN ECS_SESS* pSess, IN ECS_s8* keyName, OUT JSON_Value **pOutVal) { static ECS_u16 sequence = 0; // 创建JSON对象 JSON_Value *root_value = json_value_init_object(); JSON_Object *root_object = json_value_get_object(root_value); // 填充数据 json_object_set_string(root_object, "device_id", getDeviceID()); json_object_set_number(root_object, "timestamp", getCurrentTimestamp()); json_object_set_number(root_object, "sequence", sequence++); json_object_set_number(root_object, "counter_value", readCounterValue()); // 赋值给输出参数 *pOutVal = root_value; return SUCCESS; // 假设成功返回0 } ``` ### 通讯协议选择: 由于数据已经是JSON格式,我们可以选择: 1. **HTTP POST**:将JSON数据作为请求体发送到服务器。 2. **MQTT**:发布到一个主题,适用于物联网场景。 3. **CoAP**:如果设备资源受限,可以使用CoAP,它支持CBOR(二进制JSON)或者直接使用JSON。 ### 注册函数调用: 在注册报告函数时,我们需要填充`ECS_RPT_FUNC_NODE`结构体,注意`rptNow`可能是一个触发立即上报的标志,`isIncreaseRpt`表示是否增量上报,`interval`是上报间隔等。 ### 增量上报的JSON实现: 如果`isIncreaseRpt`为真,则需要在回调函数中判断计数值是否有变化,只有变化时才上报。同时,我们可以设计一个差值上报,比如: ```json { "device_id": "DEV12345", "timestamp": 1672531200000, "sequence": 123, "counter_delta": 10 // 相对于上一次的增量 } ``` ### 需要确认的信息: 由于用户补充了类型定义,我们需要根据实际需求调整,但之前要求的信息仍然需要确认(如计数范围、网络环境等)。 ### 完整流程: 1. 初始化时注册报告函数,创建一个`ECS_RPT_FUNC_NODE`实例,设置`func`为`counterReportFunc`,并设置其他参数(如间隔、增量上报标志等)。 2. 系统会在适当的时候(例如到达上报间隔)调用注册的回调函数。 3. 在回调函数中,我们构建JSON数据,并通过`pOutVal`输出。 4. 系统(可能是底层框架)会负责将这个JSON数据发送出去。因此,我们不需要在回调函数中实现网络发送,只需要构建JSON数据即可。 注意:根据结构体定义,可能有一个`rptNow`字段,这个字段可能用于触发立即上报,但我们不直接处理,由框架处理。 ### 注意事项: - 确保JSON库可用,并且设备有足够的内存处理JSON对象。 - 如果设备资源非常有限,使用二进制协议可能更高效,但根据回调函数的定义,必须输出JSON,所以只能使用JSON。 §§相关问题§§ 1. 如何在该JSON格式上报中实现增量上报以减少数据量? 2. 如果使用HTTP协议,如何设计服务器接口以及处理身份认证? 3. 在资源受限的设备中使用JSON是否会带来性能问题?有哪些优化方法? 4. 如何处理回调函数中JSON对象的内存管理(防止内存泄漏)? 5. 当多个报告函数同时被调用时,如何避免序列号(sequence)的竞争问题? </think> ### 基于补充接口定义的上传报文设计 根据您补充的`ECS_RPT_FUNC_NODE`结构和回调函数签名,我重新设计完整的上报方案。关键修改点已用🚩标识: --- ### 一、接口定义分析 ```c typedef ECS_s32 (*ECS_RPT_FUNC)(IN ECS_SESS* pSess, IN ECS_s8* keyName, OUT JSON_Value **pOutVal); typedef struct { ECS_s8 keyName[KEY_NAME_LEN]; // 上报键名(如"CounterData") ECS_s8 rptNow; // 立即上报标志 ECS_BOOL isIncreaseRpt; // 增量上报标志 🚩 ECS_s32 pri; // 执行优先级 ECS_s32 interval; // 上报间隔(ms) ECS_s32 time; // 注册时间戳 ECS_RPT_TYPE rptType; // 上报类型枚举 ECS_RPT_FUNC func; // 🚩核心回调函数 } ECS_RPT_FUNC_NODE; ``` **关键约束**: 1. 回调函数**必须返回JSON_Value**(通过`pOutVal`) 2. `pSess`可能包含网络会话信息 3. `rptNow`支持强制立即上报 --- ### 二、上报报文设计(JSON格式) ```c /* 计数上报JSON结构 */ ECS_s32 counterReportFunc(ECS_SESS* pSess, ECS_s8* keyName, JSON_Value** pOutVal) { static ECS_u32 sequence = 0; JSON_Value* root = json_value_init_object(); JSON_Object* obj = json_value_get_object(root); // 1. 基础字段 json_object_set_string(obj, "device_id", getDeviceID()); json_object_set_number(obj, "timestamp", getTimestampMS()); json_object_set_number(obj, "seq", sequence++); // 2. 动态数据处理 ECS_s32 current = readCounterValue(); /* 🚩 增量上报处理 */ static ECS_s32 last_value = -1; // 初始值 if(last_value < 0) { // 首次上报 json_object_set_number(obj, "init_value", current); last_value = current; } else if(current != last_value) { // 值变化 json_object_set_number(obj, "delta", current - last_value); last_value = current; } else { // 值未变化 json_object_set_null(obj, "delta"); } // 3. 元数据 json_object_set_string(obj, "report_type", (isIncreaseRpt) ? "incremental" : "full"); *pOutVal = root; // 🚩输出JSON对象 return ECS_OK; } ``` **生成的JSON报文示例**: ```json { "device_id": "DEV-2024-001", "timestamp": 1717020000000, "seq": 42, "init_value": 100, // 首次上报时存在 "delta": 5, // 增量上报值(变化时) "report_type": "incremental" } ``` --- ### 三、通讯协议实现 #### 1. 注册上报函数 ```c void registerCounterReport() { ECS_RPT_FUNC_NODE node = { .keyName = "PowerCounter", .rptNow = 0, // 0-不立即上报 .isIncreaseRpt = ECS_TRUE, // 启用增量上报 .pri = 3, .interval = 5000, // 5秒上报 .rptType = ECS_USER_RPT, .func = counterReportFunc }; ecsRptFuncReg(&node); } /* 🚩 强制上报函数 */ void triggerImmediateReport() { ECS_RPT_FUNC_NODE tmp = findNodeByName("PowerCounter"); tmp.rptNow = 1; // 设置立即上报标志 updateReportNode(&tmp); } ``` #### 2. 协议传输层实现 在系统框架内部,当`func`返回JSON后,框架应处理传输: ```c // 伪代码:框架处理流程 void processReport(ECS_RPT_FUNC_NODE* node) { JSON_Value* jval = NULL; if(node->func(pSess, node->keyName, &jval) == ECS_OK) { // 🚩 根据rptType选择协议 switch(node->rptType) { case ECS_HTTP_JSON: sendViaHTTP(json_serialize_to_string(jval)); break; case ECS_MQTT_JSON: publishMQTT(node->keyName, jval); break; case ECS_UDP_BIN: // 二进制协议需转换 sendBinary(convertToBinary(jval)); } } json_value_free(jval); // 释放内存 } ``` --- ### 四、关键问题解决方案 1. **增量上报优化**: ```c // 在回调函数开始处增加 if(node->isIncreaseRpt && !isCounterChanged()) { *pOutVal = NULL; // 返回空值跳过上报 return ECS_NO_CHANGE; } ``` 2. **协议选择建议**: | rptType 枚举值 | 推荐协议 | 适用场景 | |----------------|----------|----------| | ECS_HTTP_JSON | HTTP/1.1 + TLS | 平台对接 | | ECS_MQTT_JSON | MQTT 3.1.1 | 物联网设备 | | ECS_COAP_CBOR | CoAP + CBOR | 低功耗网络 | 3. **内存安全处理**: ```c // 确保JSON内存释放 JSON_Value* jval = NULL; ECS_s32 ret = node->func(..., &jval); if(jval) json_value_free(jval); // 🚩 必须释放 ``` --- ### 五、需要您确认的信息 1. **JSON库限制**: - 当前使用的JSON库名称(cJSON/jansson/自定义?) - 是否支持`json_object_set_null`等扩展API 2. **ECS_SESS 结构内容**: ```c typedef struct { ECS_NET_HANDLE net_handle; // 网络句柄? ECS_SECURITY_CTX* sec_ctx; // 安全上下文? // ...其他字段 } ECS_SESS; ``` 3. **上报触发机制**: - `rptNow`标志如何清零(自动/手动?) - 是否支持动态修改`interval`值 4. **错误处理要求**: - 回调函数返回错误码的具体含义 - JSON生成失败的应急处理 5. **服务器兼容性**: - 服务器期望的JSON字段命名规范 - 是否要求固定字段顺序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值