Mercurial > prosody-modules
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); |