httpserver-connection.lua 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. -- httpserver-connection
  2. -- Part of nodemcu-httpserver, provides a buffered connection object that can handle multiple
  3. -- consecutive send() calls, and buffers small payloads to send once they get big.
  4. -- For this to work, it must be used from a coroutine and owner is responsible for the final
  5. -- flush() and for closing the connection.
  6. -- Author: Philip Gladstone, Marcos Kirsch
  7. local BufferedConnection = {}
  8. -- parameter is the nodemcu-firmware connection
  9. function BufferedConnection:new(connection)
  10. local newInstance = {}
  11. newInstance.connection = connection
  12. newInstance.size = 0
  13. newInstance.data = {}
  14. -- Returns true if there was any data to be sent.
  15. function newInstance:flush()
  16. if self.size > 0 then
  17. self.connection:send(table.concat(self.data, ""))
  18. self.data = {}
  19. self.size = 0
  20. return true
  21. end
  22. return false
  23. end
  24. function newInstance:getpeer()
  25. return self.connection:getpeer()
  26. end
  27. function newInstance:send(payload)
  28. local flushThreshold = 1400
  29. local newSize = self.size + payload:len()
  30. while newSize >= flushThreshold do
  31. --STEP1: cut out piece from payload to complete threshold bytes in table
  32. local pieceSize = flushThreshold - self.size
  33. local piece = payload:sub(1, pieceSize)
  34. payload = payload:sub(pieceSize + 1, -1)
  35. --STEP2: insert piece into table
  36. table.insert(self.data, piece)
  37. piece = nil
  38. self.size = self.size + pieceSize --size should be same as flushThreshold
  39. --STEP3: flush entire table
  40. if self:flush() then
  41. coroutine.yield()
  42. end
  43. --at this point, size should be 0, because the table was just flushed
  44. newSize = self.size + payload:len()
  45. end
  46. --at this point, whatever is left in payload should be < flushThreshold
  47. if payload:len() ~= 0 then
  48. --leave remaining data in the table
  49. table.insert(self.data, payload)
  50. self.size = self.size + payload:len()
  51. end
  52. end
  53. return newInstance
  54. end
  55. return BufferedConnection