aboutsummaryrefslogtreecommitdiff
path: root/samples
diff options
context:
space:
mode:
Diffstat (limited to 'samples')
-rw-r--r--samples/README9
-rw-r--r--samples/sse.lua63
2 files changed, 72 insertions, 0 deletions
diff --git a/samples/README b/samples/README
index 4ee06b6..5fff925 100644
--- a/samples/README
+++ b/samples/README
@@ -104,6 +104,15 @@ Unix machines. It uses the lp.lua implementation, in the
104samples directory. Just run 'lua lpr.lua <filename> 104samples directory. Just run 'lua lpr.lua <filename>
105queue=<printername>' and the file will print! 105queue=<printername>' and the file will print!
106 106
107 sse.lua -- Server-Sent Events (SSE) client
108
109This little program uses socket.sse to connect to a text/event-stream
110URL and print each event received, stopping after a fixed number of
111them (5 by default). With no arguments it connects to a public live
112test feed, so you can try it with no setup at all. Just run
113
114 lua sse.lua [<url>] [<event-count>]
115
107 cddb.lua -- CDDB client 116 cddb.lua -- CDDB client
108 117
109This is the first try on a simple CDDB client. Not really 118This is the first try on a simple CDDB client. Not really
diff --git a/samples/sse.lua b/samples/sse.lua
new file mode 100644
index 0000000..16eece9
--- /dev/null
+++ b/samples/sse.lua
@@ -0,0 +1,63 @@
1-----------------------------------------------------------------------------
2-- Server-Sent Events (SSE) demo client
3-- LuaSocket sample files
4--
5-- Usage: lua sse.lua [<url>] [<event-count>]
6-- Both arguments are positional and optional; with none given, connects to
7-- a public live test feed and stops after 5 events.
8-----------------------------------------------------------------------------
9local http = require("socket.http")
10local sse = require("socket.sse")
11
12-- default target: Wikimedia's public, continuously-streaming recent-changes
13-- feed -- a real, live text/event-stream endpoint, handy for trying out
14-- socket.sse without standing up a server of your own
15local DEFAULT_URL = "https://stream.wikimedia.org/v2/stream/recentchange"
16local DEFAULT_LIMIT = 5
17
18-- shortens a long data payload for readable terminal output
19local function preview(text, limit)
20 limit = limit or 100
21 if #text > limit then return string.sub(text, 1, limit) .. "..." end
22 return text
23end
24
25-- builds a message callback that prints each received Message, then stops
26-- the stream once "limit" of them have been printed. This module parses a
27-- single request/response and never reconnects on its own (see
28-- docs/adr/0001-sse-single-shot-no-auto-reconnect.md), so a caller who wants
29-- to stop early just does what we do here: return an error from the
30-- callback, which ends the request the same way any sink error would
31local function makeprinter(limit)
32 local count = 0
33 return function(message)
34 count = count + 1
35 io.write(string.format("[%d] event=%s id=%s\n data=%s\n",
36 count, message.event, tostring(message.id), preview(message.data)))
37 if count >= limit then
38 return nil, string.format("stopped after %d events", limit)
39 end
40 return 1
41 end
42end
43
44-- main program
45arg = arg or {}
46local url = arg[1] or DEFAULT_URL
47local limit = tonumber(arg[2]) or DEFAULT_LIMIT
48
49io.write("connecting to ", url, " (stopping after ", limit, " events)\n")
50local ok, code = http.request{
51 url = url,
52 headers_callback = sse.responseheaders(makeprinter(limit))
53}
54
55if ok then
56 -- the server closed the connection on its own before we hit our limit
57 io.write("connection closed by server, code=", tostring(code), "\n")
58else
59 -- once the callback above returns an error, http.request reports it the
60 -- same way it reports any failure: (nil, message) -- so "code" here is
61 -- really our own "stopped after N events" message, not a real error
62 io.write(code, "\n")
63end