From 51c61834e3edf60b9df877f628801704adf1c70d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20P=C3=A9rez-Cerezo?= Date: Wed, 17 Apr 2019 09:15:32 +0200 Subject: First commit --- channel.lua | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 channel.lua (limited to 'channel.lua') 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 -- cgit v1.2.3