aboutsummaryrefslogtreecommitdiff
path: root/channel.lua
diff options
context:
space:
mode:
Diffstat (limited to 'channel.lua')
-rw-r--r--channel.lua93
1 files changed, 93 insertions, 0 deletions
diff --git a/channel.lua b/channel.lua
new file mode 100644
index 0000000..2885e68
--- /dev/null
+++ b/channel.lua
@@ -0,0 +1,93 @@
+-- bi-directional http-channel
+-- with long-poll GET and POST on the same URL
+
+local debug = true
+
+local function Channel(http, url, cfg)
+ cfg = cfg or {}
+ local extra_headers = cfg.extra_headers or {}
+ local timeout = cfg.timeout or 1
+ local long_poll_timeout = cfg.long_poll_timeout or 30
+ local error_retry = cfg.error_retry or 10
+
+ -- assemble post-header with json content
+ local post_headers = { "Content-Type: application/json" }
+ for _,header in pairs(cfg.extra_headers) do
+ table.insert(post_headers, header)
+ end
+
+ local recv_listeners = {}
+ local run = true
+
+ local recv_loop
+
+ recv_loop = function()
+ assert(run)
+
+ -- long-poll GET
+ http.fetch({
+ url = url,
+ extra_headers = extra_headers,
+ timeout = long_poll_timeout
+ }, function(res)
+ if res.succeeded and res.code == 200 then
+ local data = minetest.parse_json(res.data)
+
+ if debug then
+ minetest.log("action", "[webmail-rx] " .. dump(data))
+ end
+
+ if data then
+ for _,listener in pairs(recv_listeners) do
+ listener(data)
+ end
+ end
+ -- reschedule immediately
+ minetest.after(0, recv_loop)
+ else
+ -- error, retry after some time
+ minetest.after(error_retry, recv_loop)
+ end
+ end)
+ end
+
+
+ local send = function(data)
+ assert(run)
+ -- POST
+
+ if debug then
+ minetest.log("action", "[webmail-tx] " .. dump(data))
+ end
+
+ http.fetch({
+ url = url,
+ extra_headers = post_headers,
+ timeout = timeout,
+ post_data = minetest.write_json(data)
+ }, function(res)
+ -- TODO: error-handling
+ end)
+ end
+
+ local receive = function(listener)
+ table.insert(recv_listeners, listener)
+ end
+
+ local close = function()
+ run = false
+ end
+
+ recv_loop();
+
+ return {
+ send = send,
+ receive = receive,
+ close = close
+ }
+
+end
+
+
+
+return Channel