Просмотр исходного кода

Merge branch 'master' of https://gitee.com/openLuat/LuatOS

马梦阳 8 месяцев назад
Родитель
Сommit
7be24d145c
23 измененных файлов с 332 добавлено и 145 удалено
  1. 0 26
      module/Air8101/demo/socket/client/long_connection/E6.crt
  2. 0 31
      module/Air8101/demo/socket/client/long_connection/ISRG Root X1.crt
  3. 3 2
      module/Air8101/demo/socket/client/long_connection/main.lua
  4. 0 0
      module/Air8101/demo/socket/client/long_connection/netdrv/wifi_app.lua
  5. 67 0
      module/Air8101/demo/socket/client/long_connection/network_watchdog.lua
  6. 6 8
      module/Air8101/demo/socket/client/long_connection/readme.md
  7. 1 1
      module/Air8101/demo/socket/client/long_connection/tcp/tcp_client_main.lua
  8. 19 1
      module/Air8101/demo/socket/client/long_connection/tcp/tcp_client_receiver.lua
  9. 30 2
      module/Air8101/demo/socket/client/long_connection/tcp/tcp_client_sender.lua
  10. 1 1
      module/Air8101/demo/socket/client/long_connection/tcp_ssl/tcp_ssl_main.lua
  11. 19 1
      module/Air8101/demo/socket/client/long_connection/tcp_ssl/tcp_ssl_receiver.lua
  12. 30 2
      module/Air8101/demo/socket/client/long_connection/tcp_ssl/tcp_ssl_sender.lua
  13. 26 0
      module/Air8101/demo/socket/client/long_connection/tcp_ssl_ca/baidu_parent_ca.crt
  14. 0 0
      module/Air8101/demo/socket/client/long_connection/tcp_ssl_ca/sntp_app.lua
  15. 11 10
      module/Air8101/demo/socket/client/long_connection/tcp_ssl_ca/tcp_ssl_ca_main.lua
  16. 19 1
      module/Air8101/demo/socket/client/long_connection/tcp_ssl_ca/tcp_ssl_ca_receiver.lua
  17. 30 2
      module/Air8101/demo/socket/client/long_connection/tcp_ssl_ca/tcp_ssl_ca_sender.lua
  18. 0 43
      module/Air8101/demo/socket/client/long_connection/test_app.lua
  19. 21 8
      module/Air8101/demo/socket/client/long_connection/timer_app.lua
  20. 2 2
      module/Air8101/demo/socket/client/long_connection/uart_app.lua
  21. 1 1
      module/Air8101/demo/socket/client/long_connection/udp/udp_client_main.lua
  22. 19 1
      module/Air8101/demo/socket/client/long_connection/udp/udp_client_receiver.lua
  23. 27 2
      module/Air8101/demo/socket/client/long_connection/udp/udp_client_sender.lua

+ 0 - 26
module/Air8101/demo/socket/client/long_connection/E6.crt

@@ -1,26 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIEVzCCAj+gAwIBAgIRALBXPpFzlydw27SHyzpFKzgwDQYJKoZIhvcNAQELBQAw
-TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
-cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjQwMzEzMDAwMDAw
-WhcNMjcwMzEyMjM1OTU5WjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
-RW5jcnlwdDELMAkGA1UEAxMCRTYwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATZ8Z5G
-h/ghcWCoJuuj+rnq2h25EqfUJtlRFLFhfHWWvyILOR/VvtEKRqotPEoJhC6+QJVV
-6RlAN2Z17TJOdwRJ+HB7wxjnzvdxEP6sdNgA1O1tHHMWMxCcOrLqbGL0vbijgfgw
-gfUwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcD
-ATASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSTJ0aYA6lRaI6Y1sRCSNsj
-v1iU0jAfBgNVHSMEGDAWgBR5tFnme7bl5AFzgAiIyBpY9umbbjAyBggrBgEFBQcB
-AQQmMCQwIgYIKwYBBQUHMAKGFmh0dHA6Ly94MS5pLmxlbmNyLm9yZy8wEwYDVR0g
-BAwwCjAIBgZngQwBAgEwJwYDVR0fBCAwHjAcoBqgGIYWaHR0cDovL3gxLmMubGVu
-Y3Iub3JnLzANBgkqhkiG9w0BAQsFAAOCAgEAfYt7SiA1sgWGCIpunk46r4AExIRc
-MxkKgUhNlrrv1B21hOaXN/5miE+LOTbrcmU/M9yvC6MVY730GNFoL8IhJ8j8vrOL
-pMY22OP6baS1k9YMrtDTlwJHoGby04ThTUeBDksS9RiuHvicZqBedQdIF65pZuhp
-eDcGBcLiYasQr/EO5gxxtLyTmgsHSOVSBcFOn9lgv7LECPq9i7mfH3mpxgrRKSxH
-pOoZ0KXMcB+hHuvlklHntvcI0mMMQ0mhYj6qtMFStkF1RpCG3IPdIwpVCQqu8GV7
-s8ubknRzs+3C/Bm19RFOoiPpDkwvyNfvmQ14XkyqqKK5oZ8zhD32kFRQkxa8uZSu
-h4aTImFxknu39waBxIRXE4jKxlAmQc4QjFZoq1KmQqQg0J/1JF8RlFvJas1VcjLv
-YlvUB2t6npO6oQjB3l+PNf0DpQH7iUx3Wz5AjQCi6L25FjyE06q6BZ/QlmtYdl/8
-ZYao4SRqPEs/6cAiF+Qf5zg2UkaWtDphl1LKMuTNLotvsX99HP69V2faNyegodQ0
-LyTApr/vT01YPE46vNsDLgK+4cL6TrzC/a4WcmF5SRJ938zrv/duJHLXQIku5v0+
-EwOy59Hdm0PT/Er/84dDV0CSjdR/2XuZM3kpysSKLgD1cKiDA+IRguODCxfO9cyY
-Ig46v9mFmBvyH04=
------END CERTIFICATE-----

+ 0 - 31
module/Air8101/demo/socket/client/long_connection/ISRG Root X1.crt

@@ -1,31 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
-TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
-cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
-WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
-ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
-MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
-h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
-0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
-A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
-T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
-B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
-B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
-KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
-OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
-jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
-qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
-rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
-HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
-hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
-ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
-3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
-NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
-ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
-TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
-jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
-oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
-4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
-mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
-emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
------END CERTIFICATE-----

+ 3 - 2
module/Air8101/demo/socket/client/long_connection/main.lua

@@ -73,6 +73,9 @@ end
 --     log.info("mem.sys", rtos.meminfo("sys"))
 -- end, 3000)
 
+-- 加载网络环境检测看门狗功能模块
+require "network_watchdog"
+
 -- 加载WIFI网络连接管理应用功能模块
 require "wifi_app"
 
@@ -80,8 +83,6 @@ require "wifi_app"
 require "uart_app"
 -- 加载定时器应用功能模块
 require "timer_app"
--- 加载测试应用功能模块(只有调试某些接口时才需要)
--- require "test_app"
 
 -- 加载tcp client socket主应用功能模块
 require "tcp_client_main"

+ 0 - 0
module/Air8101/demo/socket/client/long_connection/wifi_app.lua → module/Air8101/demo/socket/client/long_connection/netdrv/wifi_app.lua


+ 67 - 0
module/Air8101/demo/socket/client/long_connection/network_watchdog.lua

@@ -0,0 +1,67 @@
+--[[
+@module  network_watchdog
+@summary 网络环境检测看门狗功能模块 
+@version 1.0
+@date    2025.07.23
+@author  朱天华
+@usage
+本文件为网络环境检测看门狗功能模块,监控网络环境是否工作正常(设备和服务器双向通信正常,或者至少单向通信正常),核心业务逻辑为:
+1、启动一个网络环境检测看门狗task,等待其他socket网络应用功能模块来喂狗,如果喂狗超时,则控制软件重启;
+2、如何确定“喂狗超时时间”,一般来说,有以下几个原则;
+   (1) 先确定一个最小基准值T1,2分钟或者5分钟或者10分钟,这个取值取决于具体项目需求,但是不能太短,因为开机后,在网络环境不太好的地方,网络初始化可能需要比较长的时间,一般推荐这个值不能小于2分钟;
+   (2) 再确定一个和产品业务逻辑有关的一个值T2,这个值和产品的应用业务逻辑息息相关,假设你的产品业务中:
+       <1> 服务器会定时下发数据给设备,例如设备连接上业务服务器之后,每隔3分钟,设备都会给服务器发送一次心跳,然后服务器都会立即回复一个心跳应答包;
+           这种情况下,可以取3分钟的大于等于1的倍数(例如1倍,1.5倍,2倍等等)+一段时间(例如10秒钟,如果前面是1倍,则此处必须加一段时间,给网络数据传输过程留够充足的时间);
+       <2> 如果服务器不会定时下发数据给设备,但是socket使用的是tcp传输,并且设备会定时发送数据给服务器,例如设备连接上业务服务器之后,每隔2分钟,设备都会给服务器发送一次心跳;
+           这种情况下,可以取2分钟的大于等于1的倍数(例如1倍,1.5倍,2倍等等)+一段时间(例如10秒钟,如果前面是1倍,则此处必须加一段时间,给网络数据传输过程留够充足的时间);       
+       <3> 如果服务器既不会定时或者至少一段时间下发应用数据给设备,设备也不会定时或者至少一段时间上传应用数据到服务器;
+           这种情况下,一般来说也不是长连接应用,一般来说也不需要网络业务逻辑看门狗,遇到这种情况再具体问题具体分析;
+    (3) 取T1和T2的最大值,就是“喂狗超时时间”
+3、其他socket网络业务功能模块的喂狗时机,和上面2.2的描述相对应,一般来说,可以在以下几种时间点执行喂狗动作:
+   (1) 设备收到服务器下发的数据时
+   (2) tcp连接下,设备成功发送数据到服务器时
+   (3) tcp连接成功时(不到迫不得已,这种情况下不要喂狗,如果喂狗,可能会影响以上两点的判断;
+                     因为长连接的收发数据失败会导致一直重连,重连成功喂狗就会掩盖收发数据异常,除非收发数据完全无规律,才可能在tcp连接成功时喂狗)
+4、最重要的一点是:以上所说的原则,仅仅是建议,要根据自己的实际项目业务逻辑以及自己的需求最终确定看门狗方案
+
+5、具体到本demo
+   (1) 产品业务逻辑为:
+       <1> 创建了一个tcp连接,设备每隔5秒钟发送一次数据到服务器,服务器何时下发数据给设备不确定;
+       <2> 创建了一个udp连接,设备每隔5秒钟发送一次数据到服务器,服务器何时下发数据给设备不确定;
+       <3> 创建了一个tcp ssl连接,设备每隔5秒钟发送一次数据到服务器,服务器何时下发数据给设备不确定;
+       <4> 创建了一个tcp ssl 单向校验证书连接,设备每隔5秒钟发送一次数据到服务器,服务器何时下发数据给设备不确定;
+   (2) 确定喂狗超时时间:
+       <1> 本demo支持单WIFI、单以太网、单4G网络连接外网,网络环境准备就绪预留2分钟的时间已经足够,所以最小基准值T1取值2分钟;
+       <2> 本demo中存在4路socket连接,但是这4路socket连接都没有定时或者至少一段时间,服务器下发数据给设备,所以无法基于服务器下发数据的业务逻辑来确定T2的值;
+       <3> 本demo中存在4路socket连接,每1路socket连接,设备都是5秒发送一次数据给服务器,因为5秒的时间太短,在网络环境波动的时候,数据发送延时会比较大;
+           在这个demo中,我能接受的延时发送时长是1分钟,能接受连续3次延时发送时长的失败,所以,T2取值3分钟;
+       <4> 取T1 2分钟和T2 3分钟的最大值,最终的喂狗超时时间就是3分钟;
+   (3) 确定喂狗时机:
+       <1> 4路连接中,任何1路收到服务器的下发数据时;       
+       <2> tcp、tcp ssl、tcp ssl单向校验证书3路连接中,任何1路成功发送数据给服务器时;
+6、本demo设计的网络环境检测看门狗功能模块,可以检测以下两种种的任意一种网络环境异常:
+   (1) 网络环境连续超过3分钟没有准备就绪   
+   (2) tcp、tcp ssl、tcp ssl单向校验证书3路连接中,连续3分钟没有成功发送数据到服务器;并且4路连接中,连续3分钟没有收到服务器下发的数据; 
+      
+
+本文件没有对外接口,直接在main.lua中require "network_watchdog"就可以加载运行;
+外部功能模块喂狗时,直接调用sys.publish("FEED_NETWORK_WATCHDOG")
+]]
+
+-- 网络环境检测看门狗task处理函数
+local function network_watchdog_task_func()
+    while true do
+        --如果等待180秒没有等到"FEED_NETWORK_WATCHDOG"消息,则看门狗超时
+        if not sys.waitUntil("FEED_NETWORK_WATCHDOG", 180000) then            
+            log.error("network_watchdog_task_func timeout")
+            -- 等待3秒钟,然后软件重启
+            sys.wait(3000)
+            rtos.reboot()
+        end
+    end
+end
+
+--创建并且启动一个task
+--运行这个task的处理函数network_watchdog_task_func
+sys.taskInit(network_watchdog_task_func)
+

+ 6 - 8
module/Air8101/demo/socket/client/long_connection/readme.md

@@ -63,15 +63,13 @@
 
 4、PC端浏览器访问[合宙TCP/UDP web测试工具](https://netlab.luatos.com/),点击 打开TCP SSL 按钮,会创建一个TCP SSL server,将server的地址和端口赋值给tcp_ssl_main.lua中的SERVER_ADDR和SERVER_PORT两个变量
 
-5、PC端浏览器访问[合宙TCP/UDP web测试工具](https://netlab.luatos.com/),点击 打开TCP SSL 按钮,会创建一个TCP SSL server,将server的地址和端口赋值给tcp_ssl_ca_main.lua中的SERVER_ADDR和SERVER_PORT两个变量
+5、demo脚本代码wifi_app.lua中的wlan.connect("茶室-降功耗,找合宙!", "Air123456", 1),前两个参数,修改为自己测试时wifi热点的名称和密码;注意:仅支持2.4G的wifi,不支持5G的wifi
 
-6、demo脚本代码wifi_app.lua中的wlan.connect("茶室-降功耗,找合宙!", "Air123456", 1),前两个参数,修改为自己测试时wifi热点的名称和密码;注意:仅支持2.4G的wifi,不支持5G的wifi
+6、Luatools烧录内核固件和修改后的demo脚本代码
 
-7、Luatools烧录内核固件和修改后的demo脚本代码
+7、烧录成功后,自动开机运行
 
-8、烧录成功后,自动开机运行
-
-9、[合宙TCP/UDP web测试工具](https://netlab.luatos.com/)上创建的TCP server、UDP server、TCP SSL server、TCP SSL server,一共四个server,可以看到有设备连接上来,每隔5秒钟,会接收到一段类似于 send from timer: 1 的数据,最后面的数字每次加1,类似于以下效果:
+8、[合宙TCP/UDP web测试工具](https://netlab.luatos.com/)上创建的TCP server、UDP server、TCP SSL server,一共三个server,可以看到有设备连接上来,每隔5秒钟,会接收到一段类似于 send from timer: 1 的数据,最后面的数字每次加1,类似于以下效果:
 
 ``` lua
 [2025-06-24 16:47:39.085]send from timer: 1
@@ -85,9 +83,9 @@
 ```
 
 
-10、打开PC端的串口工具,选择对应的端口,配置波特率115200,数据位8,停止位1,无奇偶校验位;
+9、打开PC端的串口工具,选择对应的端口,配置波特率115200,数据位8,停止位1,无奇偶校验位;
 
-11、PC端的串口工具输入一段数据,点击发送,在[合宙TCP/UDP web测试工具](https://netlab.luatos.com/)上的四个server页面都可以接收到数据,类似于以下效果:
+10、PC端的串口工具输入一段数据,点击发送,在[合宙TCP/UDP web测试工具](https://netlab.luatos.com/)上的四个server页面都可以接收到数据,类似于以下效果:
 
 ``` lua
 [2025-06-24 17:19:58.402]send from uart: kerjkjwr

+ 1 - 1
module/Air8101/demo/socket/client/long_connection/tcp_client_main.lua → module/Air8101/demo/socket/client/long_connection/tcp/tcp_client_main.lua

@@ -24,7 +24,7 @@ local tcp_client_sender = require "tcp_client_sender"
 -- 点击 打开TCP 按钮,会创建一个TCP server
 -- 将server的地址和端口赋值给下面这两个变量
 local SERVER_ADDR = "112.125.89.8"
-local SERVER_PORT = 42089
+local SERVER_PORT = 47391
 
 -- tcp_client_main的任务名
 local TASK_NAME = tcp_client_sender.TASK_NAME

+ 19 - 1
module/Air8101/demo/socket/client/long_connection/tcp_client_receiver.lua → module/Air8101/demo/socket/client/long_connection/tcp/tcp_client_receiver.lua

@@ -20,7 +20,22 @@ local tcp_client_receiver = {}
 -- socket数据接收缓冲区
 local recv_buff = nil
 
--- 数据接收应用入口函数
+--[[
+检查socket client是否收到数据,如果收到数据,读取并且处理完所有数据
+
+@api tcp_client_receiver.proc(socket_client)
+
+@param1 socket_client userdata
+表示由socket.create接口创建的socket client对象;
+必须传入,不允许为空或者nil;
+
+@return1 result bool
+表示处理结果,成功为true,失败为false
+
+@usage
+-- 
+tcp_client_receiver.proc(socket_client)
+]]
 function tcp_client_receiver.proc(socket_client)
     -- 如果socket数据接收缓冲区还没有申请过空间,则先申请内存空间
     if recv_buff==nil then
@@ -58,6 +73,9 @@ function tcp_client_receiver.proc(socket_client)
             -- 将数据data通过"RECV_DATA_FROM_SERVER"消息publish出去,给其他应用模块处理
             sys.publish("RECV_DATA_FROM_SERVER", "recv from tcp server: ", data)
 
+            -- 接收到数据,通知网络环境检测看门狗功能模块进行喂狗
+            sys.publish("FEED_NETWORK_WATCHDOG")
+
             -- 清空socket数据接收缓冲区中的数据
             recv_buff:del()
             -- 读取成功,但是读出来的数据为空,表示已经没有数据可读,可以退出循环了

+ 30 - 2
module/Air8101/demo/socket/client/long_connection/tcp_client_sender.lua → module/Air8101/demo/socket/client/long_connection/tcp/tcp_client_sender.lua

@@ -47,7 +47,25 @@ local function send_data_req_proc_func(tag, data, cb)
     sysplus.sendMsg(tcp_client_sender.TASK_NAME, socket.EVENT, 0)
 end
 
--- 数据发送应用逻辑处理入口
+--[[
+检查socket client是否需要发送数据,如果需要发送数据,读取并且发送完发送队列中的所有数据
+
+@api tcp_client_sender.proc(task_name, socket_client)
+
+@param1 task_name string
+表示socket.create接口创建socket client对象时所处的task的name;
+必须传入,不允许为空或者nil;
+
+@param2 socket_client userdata
+表示由socket.create接口创建的socket client对象;
+必须传入,不允许为空或者nil;
+
+@return1 result bool
+表示处理结果,成功为true,失败为false
+
+@usage
+tcp_client_sender.proc("tcp_client_main", socket_client)
+]]
 function tcp_client_sender.proc(task_name, socket_client)
     local send_item
     local result, buff_full
@@ -85,12 +103,22 @@ function tcp_client_sender.proc(task_name, socket_client)
         if send_item.cb and send_item.cb.func then
             send_item.cb.func(true, send_item.cb.para)
         end
+
+        -- 发送成功,通知网络环境检测看门狗功能模块进行喂狗
+        sys.publish("FEED_NETWORK_WATCHDOG")
     end
 
     return true
 end
 
--- 数据发送应用逻辑异常处理入口
+--[[
+socket client连接出现异常时,清空等待发送的数据,并且执行发送方的回调函数
+
+@api tcp_client_sender.exception_proc()
+
+@usage
+tcp_client_sender.exception_proc()
+]]
 function tcp_client_sender.exception_proc()
     -- 遍历数据发送队列send_queue
     while #send_queue>0 do

+ 1 - 1
module/Air8101/demo/socket/client/long_connection/tcp_ssl_main.lua → module/Air8101/demo/socket/client/long_connection/tcp_ssl/tcp_ssl_main.lua

@@ -24,7 +24,7 @@ local tcp_ssl_sender = require "tcp_ssl_sender"
 -- 点击 打开TCP SSL 按钮,会创建一个TCP SSL server
 -- 将server的地址和端口赋值给下面这两个变量
 local SERVER_ADDR = "112.125.89.8"
-local SERVER_PORT = 44358
+local SERVER_PORT = 43842
 
 -- tcp_ssl_main的任务名
 local TASK_NAME = tcp_ssl_sender.TASK_NAME

+ 19 - 1
module/Air8101/demo/socket/client/long_connection/tcp_ssl_receiver.lua → module/Air8101/demo/socket/client/long_connection/tcp_ssl/tcp_ssl_receiver.lua

@@ -20,7 +20,22 @@ local tcp_ssl_receiver = {}
 -- socket数据接收缓冲区
 local recv_buff = nil
 
--- 数据接收应用入口函数
+--[[
+检查socket client是否收到数据,如果收到数据,读取并且处理完所有数据
+
+@api tcp_ssl_receiver.proc(socket_client)
+
+@param1 socket_client userdata
+表示由socket.create接口创建的socket client对象;
+必须传入,不允许为空或者nil;
+
+@return1 result bool
+表示处理结果,成功为true,失败为false
+
+@usage
+-- 
+tcp_ssl_receiver.proc(socket_client)
+]]
 function tcp_ssl_receiver.proc(socket_client)
     -- 如果socket数据接收缓冲区还没有申请过空间,则先申请内存空间
     if recv_buff==nil then
@@ -64,6 +79,9 @@ function tcp_ssl_receiver.proc(socket_client)
             -- 将数据data通过"RECV_DATA_FROM_SERVER"消息publish出去,给其他应用模块处理
             sys.publish("RECV_DATA_FROM_SERVER", "recv from tcp_ssl server: ", data)
 
+            -- 接收到数据,通知网络环境检测看门狗功能模块进行喂狗
+            sys.publish("FEED_NETWORK_WATCHDOG")
+
             -- 清空socket数据接收缓冲区中的数据
             recv_buff:del()
         -- 读取成功,但是读出来的数据为空,表示已经没有数据可读,可以退出循环了

+ 30 - 2
module/Air8101/demo/socket/client/long_connection/tcp_ssl_sender.lua → module/Air8101/demo/socket/client/long_connection/tcp_ssl/tcp_ssl_sender.lua

@@ -47,7 +47,25 @@ local function send_data_req_proc_func(tag, data, cb)
     sysplus.sendMsg(tcp_ssl_sender.TASK_NAME, socket.EVENT, 0)
 end
 
--- 数据发送应用逻辑处理入口
+--[[
+检查socket client是否需要发送数据,如果需要发送数据,读取并且发送完发送队列中的所有数据
+
+@api tcp_ssl_sender.proc(task_name, socket_client)
+
+@param1 task_name string
+表示socket.create接口创建socket client对象时所处的task的name;
+必须传入,不允许为空或者nil;
+
+@param2 socket_client userdata
+表示由socket.create接口创建的socket client对象;
+必须传入,不允许为空或者nil;
+
+@return1 result bool
+表示处理结果,成功为true,失败为false
+
+@usage
+tcp_ssl_sender.proc("tcp_client_main", socket_client)
+]]
 function tcp_ssl_sender.proc(task_name, socket_client)
     local send_item
     local result, buff_full
@@ -85,12 +103,22 @@ function tcp_ssl_sender.proc(task_name, socket_client)
         if send_item.cb and send_item.cb.func then
             send_item.cb.func(true, send_item.cb.para)
         end
+
+        -- 发送成功,通知网络环境检测看门狗功能模块进行喂狗
+        sys.publish("FEED_NETWORK_WATCHDOG")
     end
 
     return true
 end
 
--- 数据发送应用逻辑异常处理入口
+--[[
+socket client连接出现异常时,清空等待发送的数据,并且执行发送方的回调函数
+
+@api tcp_ssl_sender.exception_proc()
+
+@usage
+tcp_ssl_sender.exception_proc()
+]]
 function tcp_ssl_sender.exception_proc()
     -- 遍历数据发送队列send_queue
     while #send_queue>0 do

+ 26 - 0
module/Air8101/demo/socket/client/long_connection/tcp_ssl_ca/baidu_parent_ca.crt

@@ -0,0 +1,26 @@
+-----BEGIN CERTIFICATE-----
+MIIETjCCAzagAwIBAgINAe5fIh38YjvUMzqFVzANBgkqhkiG9w0BAQsFADBMMSAw
+HgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFs
+U2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjAeFw0xODExMjEwMDAwMDBaFw0yODEx
+MjEwMDAwMDBaMFAxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52
+LXNhMSYwJAYDVQQDEx1HbG9iYWxTaWduIFJTQSBPViBTU0wgQ0EgMjAxODCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKdaydUMGCEAI9WXD+uu3Vxoa2uP
+UGATeoHLl+6OimGUSyZ59gSnKvuk2la77qCk8HuKf1UfR5NhDW5xUTolJAgvjOH3
+idaSz6+zpz8w7bXfIa7+9UQX/dhj2S/TgVprX9NHsKzyqzskeU8fxy7quRU6fBhM
+abO1IFkJXinDY+YuRluqlJBJDrnw9UqhCS98NE3QvADFBlV5Bs6i0BDxSEPouVq1
+lVW9MdIbPYa+oewNEtssmSStR8JvA+Z6cLVwzM0nLKWMjsIYPJLJLnNvBhBWk0Cq
+o8VS++XFBdZpaFwGue5RieGKDkFNm5KQConpFmvv73W+eka440eKHRwup08CAwEA
+AaOCASkwggElMA4GA1UdDwEB/wQEAwIBhjASBgNVHRMBAf8ECDAGAQH/AgEAMB0G
+A1UdDgQWBBT473/yzXhnqN5vjySNiPGHAwKz6zAfBgNVHSMEGDAWgBSP8Et/qC5F
+JK5NUPpjmove4t0bvDA+BggrBgEFBQcBAQQyMDAwLgYIKwYBBQUHMAGGImh0dHA6
+Ly9vY3NwMi5nbG9iYWxzaWduLmNvbS9yb290cjMwNgYDVR0fBC8wLTAroCmgJ4Yl
+aHR0cDovL2NybC5nbG9iYWxzaWduLmNvbS9yb290LXIzLmNybDBHBgNVHSAEQDA+
+MDwGBFUdIAAwNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93d3cuZ2xvYmFsc2lnbi5j
+b20vcmVwb3NpdG9yeS8wDQYJKoZIhvcNAQELBQADggEBAJmQyC1fQorUC2bbmANz
+EdSIhlIoU4r7rd/9c446ZwTbw1MUcBQJfMPg+NccmBqixD7b6QDjynCy8SIwIVbb
+0615XoFYC20UgDX1b10d65pHBf9ZjQCxQNqQmJYaumxtf4z1s4DfjGRzNpZ5eWl0
+6r/4ngGPoJVpjemEuunl1Ig423g7mNA2eymw0lIYkN5SQwCuaifIFJ6GlazhgDEw
+fpolu4usBCOmmQDo8dIm7A9+O4orkjgTHY+GzYZSR+Y0fFukAj6KYXwidlNalFMz
+hriSqHKvoflShx8xpfywgVcvzfTO3PYkz6fiNJBonf6q8amaEsybwMbDqKWwIX7e
+SPY=
+-----END CERTIFICATE-----

+ 0 - 0
module/Air8101/demo/socket/client/long_connection/sntp_app.lua → module/Air8101/demo/socket/client/long_connection/tcp_ssl_ca/sntp_app.lua


+ 11 - 10
module/Air8101/demo/socket/client/long_connection/tcp_ssl_ca_main.lua → module/Air8101/demo/socket/client/long_connection/tcp_ssl_ca/tcp_ssl_ca_main.lua

@@ -20,11 +20,9 @@ local tcp_ssl_ca_receiver = require "tcp_ssl_ca_receiver"
 -- 加载tcp_ssl_ca client socket数据发送功能模块
 local tcp_ssl_ca_sender = require "tcp_ssl_ca_sender"
 
--- 电脑访问:https://netlab.luatos.com/
--- 点击 打开TCP SSL 按钮,会创建一个TCP SSL server
--- 将server的地址和端口赋值给下面这两个变量
-local SERVER_ADDR = "112.125.89.8"
-local SERVER_PORT = 42347
+-- https://www.baidu.com网站服务器,地址为"www.baidu.com",端口为443
+local SERVER_ADDR = "www.baidu.com"
+local SERVER_PORT = 443
 
 -- tcp_ssl_ca_main的任务名
 local TASK_NAME = tcp_ssl_ca_sender.TASK_NAME
@@ -41,12 +39,15 @@ local function tcp_ssl_ca_main_task_func()
     local socket_client
     local result, para1, para2
 
-    -- 用来验证server证书是否合法的ca证书文件为E6.crt
+    -- 用来验证server证书是否合法的ca证书文件为baidu_parent_ca.crt
+    -- 此ca证书的有效期截止到2028年11月21日
     -- 将这个ca证书文件的内容读取出来,赋值给server_ca_cert
-    -- 注意:此处的ca证书文件仅用来验证netlab创建的server证书
+    -- 注意:此处的ca证书文件仅用来验证baidu网站的server证书
+    -- baidu网站的server证书有效期截止到2026年8月10日
+    -- 在有效期之前,baidu会更换server证书,如果server证书更换后,此处验证使用的baidu_parent_ca.crt也可能需要更换
+    -- 使用电脑上的网页浏览器访问https://www.baidu.com,可以实时看到baidu的server证书以及baidu_parent_ca.crt
     -- 如果你使用的是自己的server,要替换为自己server证书对应的ca证书文件
-    -- local server_ca_cert = io.readFile("/luadb/E6.crt")
-    local server_ca_cert = io.readFile("/luadb/ISRG Root X1.crt")
+    local server_ca_cert = io.readFile("/luadb/baidu_parent_ca.crt")
 
     while true do
         -- 如果WIFI还没有连接成功,一直在这里循环等待
@@ -75,7 +76,7 @@ local function tcp_ssl_ca_main_task_func()
         -- 2、任何证书都有有效期,无论是ca证书还是server证书,必须在有效期截止之前,及时更换证书,延长有效期,否则证书校验会失败;
         -- 3、如果要更换ca证书,需要在设备端远程升级,必须保证ca证书失效之前升级成功,否则校验失败,就无法连接server;
         -- 综上所述,证书校验虽然安全,可以验证身份,但是后续维护成本比较高;除非有需要,否则可以不配置证书校验功能;
-        -- 另外,使用https://netlab.luatos.com/创建的TCP SSL Server,使用的server证书有可能过了有效期;
+        -- 另外,如果使用https://netlab.luatos.com/创建的TCP SSL Server,使用的server证书有可能过了有效期;
         -- 如果过了有效期,使用本文件无法连接成功tcp ssl ca server,遇到这种问题,可以在main.lua中打开socket.sslLog(3),观察Luatools的日志,如果出现类似于下面的日志
         -- expires on        : 2020-12-27 15:46:55
         -- 表示证书有效期截止到2020-12-27 15:46:55,明显就是证书已经过了有效期

+ 19 - 1
module/Air8101/demo/socket/client/long_connection/tcp_ssl_ca_receiver.lua → module/Air8101/demo/socket/client/long_connection/tcp_ssl_ca/tcp_ssl_ca_receiver.lua

@@ -20,7 +20,22 @@ local tcp_ssl_ca_receiver = {}
 -- socket数据接收缓冲区
 local recv_buff = nil
 
--- 数据接收应用入口函数
+--[[
+检查socket client是否收到数据,如果收到数据,读取并且处理完所有数据
+
+@api tcp_ssl_ca_receiver.proc(socket_client)
+
+@param1 socket_client userdata
+表示由socket.create接口创建的socket client对象;
+必须传入,不允许为空或者nil;
+
+@return1 result bool
+表示处理结果,成功为true,失败为false
+
+@usage
+-- 
+tcp_ssl_ca_receiver.proc(socket_client)
+]]
 function tcp_ssl_ca_receiver.proc(socket_client)
     -- 如果socket数据接收缓冲区还没有申请过空间,则先申请内存空间
     if recv_buff==nil then
@@ -64,6 +79,9 @@ function tcp_ssl_ca_receiver.proc(socket_client)
             -- 将数据data通过"RECV_DATA_FROM_SERVER"消息publish出去,给其他应用模块处理
             sys.publish("RECV_DATA_FROM_SERVER", "recv from tcp_ssl_ca server: ", data)
 
+            -- 接收到数据,通知网络环境检测看门狗功能模块进行喂狗
+            sys.publish("FEED_NETWORK_WATCHDOG")
+
             -- 清空socket数据接收缓冲区中的数据
             recv_buff:del()
             -- 读取成功,但是读出来的数据为空,表示已经没有数据可读,可以退出循环了

+ 30 - 2
module/Air8101/demo/socket/client/long_connection/tcp_ssl_ca_sender.lua → module/Air8101/demo/socket/client/long_connection/tcp_ssl_ca/tcp_ssl_ca_sender.lua

@@ -47,7 +47,25 @@ local function send_data_req_proc_func(tag, data, cb)
     sysplus.sendMsg(tcp_ssl_ca_sender.TASK_NAME, socket.EVENT, 0)
 end
 
--- 数据发送应用逻辑处理入口
+--[[
+检查socket client是否需要发送数据,如果需要发送数据,读取并且发送完发送队列中的所有数据
+
+@api tcp_ssl_ca_sender.proc(task_name, socket_client)
+
+@param1 task_name string
+表示socket.create接口创建socket client对象时所处的task的name;
+必须传入,不允许为空或者nil;
+
+@param2 socket_client userdata
+表示由socket.create接口创建的socket client对象;
+必须传入,不允许为空或者nil;
+
+@return1 result bool
+表示处理结果,成功为true,失败为false
+
+@usage
+tcp_ssl_ca_sender.proc("tcp_client_main", socket_client)
+]]
 function tcp_ssl_ca_sender.proc(task_name, socket_client)
     local send_item
     local result, buff_full
@@ -85,12 +103,22 @@ function tcp_ssl_ca_sender.proc(task_name, socket_client)
         if send_item.cb and send_item.cb.func then
             send_item.cb.func(true, send_item.cb.para)
         end
+
+        -- 发送成功,通知网络环境检测看门狗功能模块进行喂狗
+        sys.publish("FEED_NETWORK_WATCHDOG")
     end
 
     return true
 end
 
--- 数据发送应用逻辑异常处理入口
+--[[
+socket client连接出现异常时,清空等待发送的数据,并且执行发送方的回调函数
+
+@api tcp_ssl_ca_sender.exception_proc()
+
+@usage
+tcp_ssl_ca_sender.exception_proc()
+]]
 function tcp_ssl_ca_sender.exception_proc()
     -- 遍历数据发送队列send_queue
     while #send_queue>0 do

+ 0 - 43
module/Air8101/demo/socket/client/long_connection/test_app.lua

@@ -1,43 +0,0 @@
---[[
-本文件为测试应用功能模块,用来测试其他功能模块的外部接口;
-仅调试需要,项目量产时不需要;
-]]
-
---[[
-@module  test_app
-@summary 测试应用功能模块 
-@version 1.0
-@date    2025.07.01
-@author  朱天华
-@usage
-本文件为测试应用功能模块,用来测试其他功能模块的外部接口;
-仅调试需要,项目量产时不需要;
-]]
-
-
--- 模拟四个socket client从server收到了数据,然后publish消息"RECV_DATA_FROM_SERVER"
-sys.taskInit(function()
-    local cnt = 0
-
-    while true do
-        cnt = cnt+1
-
-        sys.wait(1000)
-        sys.publish("RECV_DATA_FROM_SERVER", "recv from tcp server: ", cnt)
-
-        sys.wait(1000)
-        sys.publish("RECV_DATA_FROM_SERVER", "recv from udp server: ", cnt)
-
-        sys.wait(1000)
-        sys.publish("RECV_DATA_FROM_SERVER", "recv from tcp ssl server: ", cnt)
-
-        sys.wait(1000)
-        sys.publish("RECV_DATA_FROM_SERVER", "recv from tcp ssl ca server: ", cnt)
-    end
-
-end)
-
--- 模拟订阅处理串口应用功能模块和定时器应用功能模块的"SEND_DATA_REQ"消息
-sys.subscribe("SEND_DATA_REQ", function(tag, data)
-    log.info("test_app.SEND_DATA_REQ", "send from "..tag..": "..data)
-end)

+ 21 - 8
module/Air8101/demo/socket/client/long_connection/timer_app.lua

@@ -9,20 +9,33 @@
 创建一个5秒的循环定时器,每次产生一段数据,通知四个socket client进行处理;
 
 本文件的对外接口有一个:
-1、sys.publish("SEND_DATA_REQ", "timer", data),通过publish通知其他应用功能模块处理data数据
+1、sys.publish("SEND_DATA_REQ", "timer", data, {func=send_data_cbfunc, para="timer"..data}),通过publish通知socket client数据发送功能模块发送data数据;
+   数据发送结果通过执行回调函数send_data_cbfunc通知本功能模块;
 ]]
 
 local data = 1
 
--- 循环定时器处理函数
-local function send_data_req_timer_loop_func()
+-- 数据发送结果回调函数
+-- result:发送结果,true为发送成功,false为发送失败
+-- para:回调参数,sys.publish("SEND_DATA_REQ", "timer", data, {func=send_data_cbfunc, para="timer"..data})中携带的para
+local function send_data_cbfunc(result, para)
+    log.info("send_data_cbfunc", result, para)
+    -- 无论上一次发送成功还是失败,启动一个5秒的定时器,5秒后发送下次数据
+    sys.timerStart(send_data_req_timer_cbfunc, 5000)
+end
+
+-- 定时器回调函数
+function send_data_req_timer_cbfunc()
     -- 发布消息"SEND_DATA_REQ"
     -- 携带的第一个参数"timer"表示是定时器应用模块发布的消息
-    -- 携带的第一个参数data为要发送的原始数据
-    sys.publish("SEND_DATA_REQ", "timer", data)
+    -- 携带的第二个参数data为要发送的原始数据
+    -- 携带的第三个参数cb为发送结果回调(可以为空,如果为空,表示不关心socket client发送数据成功还是失败),其中:
+    --       cb.func为回调函数(可以为空,如果为空,表示不关心socket client发送数据成功还是失败)
+    --       cb.para为回调函数的第二个参数(可以为空),回调函数的第一个参数为发送结果(true表示成功,false表示失败)
+    sys.publish("SEND_DATA_REQ", "timer", data, {func=send_data_cbfunc, para="timer"..data})
     data = data+1
 end
 
--- 启动一个5秒的循环定时器
--- 每隔5秒执行一次send_data_req_timer_loop_func函数
-sys.timerLoopStart(send_data_req_timer_loop_func, 5000)
+-- 启动一个5秒的单次定时器
+-- 时间到达后,执行一次send_data_req_timer_cbfunc函数
+sys.timerStart(send_data_req_timer_cbfunc, 5000)

+ 2 - 2
module/Air8101/demo/socket/client/long_connection/uart_app.lua

@@ -12,8 +12,8 @@
 4、收到四个socket client从socket server接收到的数据后,将数据通过uart1发送到pc端串口工具;
 
 本文件的对外接口有两个:
-1、sys.publish("SEND_DATA_REQ", "uart", read_buf),通过publish通知其他应用功能模块处理read_buf数据
-2、sys.subscribe("RECV_DATA_FROM_SERVER", recv_data_from_server_proc),订阅RECV_DATA_FROM_SERVER消息,处理消息携带的数据;
+1、sys.publish("SEND_DATA_REQ", "uart", read_buf),通过publish通知socket client数据发送功能模块发送read_buf数据,不关心数据发送成功还是失败
+2、sys.subscribe("RECV_DATA_FROM_SERVER", recv_data_from_server_proc),订阅RECV_DATA_FROM_SERVER消息,处理消息携带的数据;
 ]]
 
 

+ 1 - 1
module/Air8101/demo/socket/client/long_connection/udp_client_main.lua → module/Air8101/demo/socket/client/long_connection/udp/udp_client_main.lua

@@ -24,7 +24,7 @@ local udp_client_sender = require "udp_client_sender"
 -- 点击 打开UDP 按钮,会创建一个UDP server
 -- 将server的地址和端口赋值给下面这两个变量
 local SERVER_ADDR = "112.125.89.8"
-local SERVER_PORT = 42104
+local SERVER_PORT = 42250
 
 -- udp_client_main的任务名
 local TASK_NAME = udp_client_sender.TASK_NAME

+ 19 - 1
module/Air8101/demo/socket/client/long_connection/udp_client_receiver.lua → module/Air8101/demo/socket/client/long_connection/udp/udp_client_receiver.lua

@@ -20,7 +20,22 @@ local udp_client_receiver = {}
 -- socket数据接收缓冲区
 local recv_buff = nil
 
--- 数据接收应用入口函数
+--[[
+检查socket client是否收到数据,如果收到数据,读取并且处理完所有数据
+
+@api udp_client_receiver.proc(socket_client)
+
+@param1 socket_client userdata
+表示由socket.create接口创建的socket client对象;
+必须传入,不允许为空或者nil;
+
+@return1 result bool
+表示处理结果,成功为true,失败为false
+
+@usage
+-- 
+udp_client_receiver.proc(socket_client)
+]]
 function udp_client_receiver.proc(socket_client)
     -- 如果socket数据接收缓冲区还没有申请过空间,则先申请内存空间
     if recv_buff==nil then
@@ -58,6 +73,9 @@ function udp_client_receiver.proc(socket_client)
             -- 将数据data通过"RECV_DATA_FROM_SERVER"消息publish出去,给其他应用模块处理
             sys.publish("RECV_DATA_FROM_SERVER", "recv from udp server: ", data)
 
+            -- 接收到数据,通知网络环境检测看门狗功能模块进行喂狗
+            sys.publish("FEED_NETWORK_WATCHDOG")
+
             -- 清空socket数据接收缓冲区中的数据
             recv_buff:del()
             -- 读取成功,但是读出来的数据为空,表示已经没有数据可读,可以退出循环了

+ 27 - 2
module/Air8101/demo/socket/client/long_connection/udp_client_sender.lua → module/Air8101/demo/socket/client/long_connection/udp/udp_client_sender.lua

@@ -47,7 +47,25 @@ local function send_data_req_proc_func(tag, data, cb)
     sysplus.sendMsg(udp_client_sender.TASK_NAME, socket.EVENT, 0)
 end
 
--- 数据发送应用逻辑处理入口
+--[[
+检查socket client是否需要发送数据,如果需要发送数据,读取并且发送完发送队列中的所有数据
+
+@api udp_client_sender.proc(task_name, socket_client)
+
+@param1 task_name string
+表示socket.create接口创建socket client对象时所处的task的name;
+必须传入,不允许为空或者nil;
+
+@param2 socket_client userdata
+表示由socket.create接口创建的socket client对象;
+必须传入,不允许为空或者nil;
+
+@return1 result bool
+表示处理结果,成功为true,失败为false
+
+@usage
+udp_client_sender.proc("tcp_client_main", socket_client)
+]]
 function udp_client_sender.proc(task_name, socket_client)
     local send_item
     local result, buff_full
@@ -90,7 +108,14 @@ function udp_client_sender.proc(task_name, socket_client)
     return true
 end
 
--- 数据发送应用逻辑异常处理入口
+--[[
+socket client连接出现异常时,清空等待发送的数据,并且执行发送方的回调函数
+
+@api udp_client_sender.exception_proc()
+
+@usage
+udp_client_sender.exception_proc()
+]]
 function udp_client_sender.exception_proc()
     -- 遍历数据发送队列send_queue
     while #send_queue>0 do