httpserver-connection.lua 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  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. 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:send(payload)
  25. local flushThreshold = 1400
  26. local newSize = self.size + payload:len()
  27. while newSize >= flushThreshold do
  28. --STEP1: cut out piece from payload to complete threshold bytes in table
  29. local pieceSize = flushThreshold - self.size
  30. local piece = payload:sub(1, pieceSize)
  31. payload = payload:sub(pieceSize + 1, -1)
  32. --STEP2: insert piece into table
  33. table.insert(self.data, piece)
  34. piece = nil
  35. self.size = self.size + pieceSize --size should be same as flushThreshold
  36. --STEP3: flush entire table
  37. if self:flush() then
  38. coroutine.yield()
  39. end
  40. --at this point, size should be 0, because the table was just flushed
  41. newSize = self.size + payload:len()
  42. end
  43. --at this point, whatever is left in payload should be < flushThreshold
  44. if payload:len() ~= 0 then
  45. --leave remaining data in the table
  46. table.insert(self.data, payload)
  47. self.size = self.size + payload:len()
  48. end
  49. end
  50. return newInstance
  51. end
  52. return BufferedConnection