comparison 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
parents
children 39485b9bbdd6
comparison
equal deleted inserted replaced
2882:6f289283feb1 2883:7c16afc70d11
1 module:depends("http");
2
3 local jid_split = require "util.jid".split;
4 local json = require "util.json";
5
6 local streams = {};
7
8 function client_closed(response)
9 local node = response._eventsource_node;
10 module:log("debug", "Destroying client for %q", node);
11 streams[node][response] = nil;
12 if next(streams[node]) == nil then
13 streams[node] = nil;
14 end
15 end
16
17 function serve_stream(event, node)
18 module:log("debug", "Client subscribed to: %s", node);
19
20 local response = event.response;
21 response.on_destroy = client_closed;
22 response._eventsource_node = node;
23
24 response.conn:write(table.concat({
25 "HTTP/1.1 200 OK";
26 "Content-Type: text/event-stream";
27 "Access-Control-Allow-Origin: *";
28 "Access-Control-Allow-Methods: GET";
29 "Access-Control-Max-Age: 7200";
30 "";
31 "";
32 }, "\r\n"));
33
34 local clientlist = streams[node];
35 if not clientlist then
36 clientlist = {};
37 streams[node] = clientlist;
38 end
39 clientlist[response] = response.conn;
40
41 return true;
42 end
43
44 function handle_message(event)
45 local room, stanza = event.room, event.stanza;
46 local node = (jid_split(event.room.jid));
47 local clientlist = streams[node];
48 if not clientlist then module:log("debug", "No clients for %q", node); return; end
49
50 -- Extract body from message
51 local body = event.stanza:get_child_text("body");
52 if not body then
53 return;
54 end
55 local nick = select(3, jid_split(stanza.attr.from));
56 -- Encode body and broadcast to eventsource subscribers
57 local json_data = json.encode({
58 nick = nick;
59 body = body;
60 });
61 local data = "data: "..json_data:gsub("\n", "\ndata: \n").."\n\n";
62 for response, conn in pairs(clientlist) do
63 conn:write(data);
64 end
65 end
66
67 module:provides("http", {
68 name = "eventsource";
69 route = {
70 ["GET /*"] = serve_stream;
71 };
72 });
73
74
75 module:hook("muc-broadcast-message", handle_message);