--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_muc_eventsource/mod_muc_eventsource.lua Mon Feb 19 22:17:38 2018 +0000
@@ -0,0 +1,75 @@
+module:depends("http");
+
+local jid_split = require "util.jid".split;
+local json = require "util.json";
+
+local streams = {};
+
+function client_closed(response)
+ local node = response._eventsource_node;
+ module:log("debug", "Destroying client for %q", node);
+ streams[node][response] = nil;
+ if next(streams[node]) == nil then
+ streams[node] = nil;
+ end
+end
+
+function serve_stream(event, node)
+ module:log("debug", "Client subscribed to: %s", node);
+
+ local response = event.response;
+ response.on_destroy = client_closed;
+ response._eventsource_node = node;
+
+ response.conn:write(table.concat({
+ "HTTP/1.1 200 OK";
+ "Content-Type: text/event-stream";
+ "Access-Control-Allow-Origin: *";
+ "Access-Control-Allow-Methods: GET";
+ "Access-Control-Max-Age: 7200";
+ "";
+ "";
+ }, "\r\n"));
+
+ local clientlist = streams[node];
+ if not clientlist then
+ clientlist = {};
+ streams[node] = clientlist;
+ end
+ clientlist[response] = response.conn;
+
+ return true;
+end
+
+function handle_message(event)
+ local room, stanza = event.room, event.stanza;
+ local node = (jid_split(event.room.jid));
+ local clientlist = streams[node];
+ if not clientlist then module:log("debug", "No clients for %q", node); return; end
+
+ -- Extract body from message
+ local body = event.stanza:get_child_text("body");
+ if not body then
+ return;
+ end
+ local nick = select(3, jid_split(stanza.attr.from));
+ -- Encode body and broadcast to eventsource subscribers
+ local json_data = json.encode({
+ nick = nick;
+ body = body;
+ });
+ local data = "data: "..json_data:gsub("\n", "\ndata: \n").."\n\n";
+ for response, conn in pairs(clientlist) do
+ conn:write(data);
+ end
+end
+
+module:provides("http", {
+ name = "eventsource";
+ route = {
+ ["GET /*"] = serve_stream;
+ };
+});
+
+
+module:hook("muc-broadcast-message", handle_message);