tcp_server_sender.lua 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. --[[
  2. @module tcp_server_sender
  3. @summary tcp server socket数据发送应用功能模块
  4. @version 1.0
  5. @date 2025.11.15
  6. @author 王世豪
  7. @usage
  8. 本文件为tcp server socket数据发送应用功能模块,核心业务逻辑为:
  9. 1、sys.subscribe("SEND_DATA_REQ", send_data_req_proc_func)订阅"SEND_DATA_REQ"消息,将其他应用模块需要发送的数据存储到队列send_queue中;
  10. 2、tcp_server_main主任务调用tcp_server_sender.proc接口,遍历队列send_queue,逐条发送数据到server;
  11. 3、tcp server socket和server之间的连接如果出现异常,tcp_server_main主任务调用tcp_server_sender.exception_proc接口,丢弃掉队列send_queue中未发送的数据;
  12. 4、任何一条数据无论发送成功还是失败,只要这条数据有回调函数,都会通过回调函数通知数据发送方;
  13. 本文件的对外接口有3个:
  14. 1、sys.subscribe("SEND_DATA_REQ", send_data_req_proc_func):订阅"SEND_DATA_REQ"消息;
  15. 其他应用模块如果需要发送数据,直接sys.publish这个消息即可,将需要发送的数据以及回调函数和回调参数一起publish出去;
  16. 本demo项目中uart_app.lua和timer_app.lua中publish了这个消息;
  17. 2、tcp_server_sender.proc:数据发送应用逻辑处理入口,在tcp_server_main.lua中调用;
  18. 3、tcp_server_sender.exception_proc:数据发送应用逻辑异常处理入口,在tcp_server_main.lua中调用;
  19. ]]
  20. local tcp_server_sender = {}
  21. local libnet = require "libnet"
  22. --[[
  23. 数据发送队列,数据结构为:
  24. {
  25. [1] = {data="data1", cb={func=callback_function1, para=callback_para1}},
  26. [2] = {data="data2", cb={func=callback_function2, para=callback_para2}},
  27. }
  28. data的内容为真正要发送的数据,必须存在;
  29. func的内容为数据发送结果的用户回调函数,可以不存在
  30. para的内容为数据发送结果的用户回调函数的回调参数,可以不存在;
  31. ]]
  32. local send_queue = {}
  33. -- tcp_server_main的任务名
  34. tcp_server_sender.TASK_NAME = "tcp_server_main"
  35. -- "SEND_DATA_REQ"消息的处理函数
  36. local function send_data_req_proc_func(tag, data, cb)
  37. -- 将原始数据增加前缀,然后插入到发送队列send_queue中
  38. table.insert(send_queue, {data="send from "..tag..": "..data, cb=cb})
  39. -- 通知tcp_server_main主任务有数据需要发送
  40. -- tcp_server_main主任务如果处在libnet.wait调用的阻塞等待状态,就会退出阻塞状态
  41. sys.sendMsg(tcp_server_sender.TASK_NAME, socket.EVENT, 0)
  42. end
  43. --[[
  44. 检查socket server是否需要发送数据,如果需要发送数据,读取并且发送完发送队列中的所有数据
  45. @api tcp_server_sender.proc(task_name, socket_server)
  46. @param1 task_name string
  47. 表示socket.create接口创建socket server对象时所处的task的name;
  48. 必须传入,不允许为空或者nil;
  49. @param2 socket_server userdata
  50. 表示由socket.create接口创建的socket server对象;
  51. 必须传入,不允许为空或者nil;
  52. @return1 result bool
  53. 表示处理结果,成功为true,失败为false
  54. @usage
  55. tcp_server_sender.proc("tcp_server_main", socket_server)
  56. ]]
  57. function tcp_server_sender.proc(task_name, netc)
  58. local send_item
  59. local result, buff_full
  60. -- 遍历数据发送队列send_queue
  61. while #send_queue>0 do
  62. -- 取出来第一条数据赋值给send_item
  63. -- 同时从队列send_queue中删除这一条数据
  64. send_item = table.remove(send_queue,1)
  65. -- 发送这条数据,超时时间15秒钟
  66. result, buff_full = libnet.tx(task_name, 15000, netc, send_item.data)
  67. -- 检查发送结果
  68. if not result then
  69. log.error("tcp_server_sender.proc", "libnet.tx error")
  70. -- 如果当前发送的数据有用户回调函数,则执行用户回调函数
  71. if send_item.cb and send_item.cb.func then
  72. send_item.cb.func(false, send_item.cb.para)
  73. end
  74. return false
  75. end
  76. -- 如果内核固件中缓冲区满了,则将send_item再次插入到send_queue的队首位置,等待下次尝试发送
  77. if buff_full then
  78. log.error("tcp_client_sender.proc", "buffer is full, wait for the next time")
  79. table.insert(send_queue, 1, send_item)
  80. return true
  81. end
  82. log.info("tcp_server_sender.proc", "send success")
  83. -- 发送成功,如果当前发送的数据有用户回调函数,则执行用户回调函数
  84. if send_item.cb and send_item.cb.func then
  85. send_item.cb.func(true, send_item.cb.para)
  86. end
  87. end
  88. return true
  89. end
  90. --[[
  91. socket server连接出现异常时,清空等待发送的数据,并且执行发送方的回调函数
  92. @api tcp_server_sender.exception_proc()
  93. @usage
  94. tcp_server_sender.exception_proc()
  95. ]]
  96. function tcp_server_sender.exception_proc()
  97. -- 遍历数据发送队列send_queue
  98. while #send_queue>0 do
  99. local send_item = table.remove(send_queue,1)
  100. -- 发送失败,如果当前发送的数据有用户回调函数,则执行用户回调函数
  101. if send_item.cb and send_item.cb.func then
  102. send_item.cb.func(false, send_item.cb.para)
  103. end
  104. end
  105. end
  106. -- 订阅"SEND_DATA_REQ"消息;
  107. -- 其他应用模块如果需要发送数据,直接sys.publish这个消息即可,将需要发送的数据以及回调函数和回调参数一起publish出去;
  108. -- 本demo项目中uart_app.lua和timer_app.lua中publish了这个消息;
  109. sys.subscribe("SEND_DATA_REQ", send_data_req_proc_func)
  110. return tcp_server_sender