Software /
code /
prosody-modules
File
mod_muc_eventsource/mod_muc_eventsource.lua @ 2883:7c16afc70d11
mod_muc_eventsource: New module forked from mod_pubsub_eventsource, exposes room message stream over SSE
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Mon, 19 Feb 2018 22:17:38 +0000 |
child | 2897:39485b9bbdd6 |
line wrap: on
line source
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);