comparison mod_pubsub_eventsource/mod_pubsub_eventsource.lua @ 858:28dba9608499

mod_pubsub_eventsource: An experimental plugin for allowing non-XMPP subscriptions to pubsub nodes over HTML5's server-sent events (SSE/EventSource) API
author Matthew Wild <mwild1@gmail.com>
date Thu, 15 Nov 2012 13:27:53 -0500
parents
children 2380a5d71448
comparison
equal deleted inserted replaced
857:1393af36ec9c 858:28dba9608499
1 module:depends("http");
2 module:depends("pubsub");
3
4 local streams = {};
5
6 local service = hosts[module.host].modules.pubsub.service;
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 "";
28 "";
29 }, "\r\n"));
30
31 local clientlist = streams[node];
32 if not clientlist then
33 clientlist = {};
34 streams[node] = clientlist;
35 end
36 clientlist[response] = response.conn;
37
38 return true;
39 end
40
41 function handle_update(event)
42 module:log("debug", "Item published: %q", event.node);
43 local node = event.node;
44 local clientlist = streams[node];
45 local data = "data: "..tostring(event.item):gsub("\n", "\ndata: \n").."\n\n";
46 if not clientlist then module:log("debug", "No clients for %q", node); return; end
47 for response, conn in pairs(clientlist) do
48 conn:write(data);
49 end
50 end
51
52 module:provides("http", {
53 name = "eventsource";
54 route = {
55 ["GET /*"] = serve_stream;
56 };
57 });
58
59 module:hook_object_event(service.events, "item-published", handle_update);