diff options
Diffstat (limited to '')
| -rw-r--r-- | samples/sse.lua | 63 |
1 files changed, 63 insertions, 0 deletions
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 | ----------------------------------------------------------------------------- | ||
| 9 | local http = require("socket.http") | ||
| 10 | local 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 | ||
| 15 | local DEFAULT_URL = "https://stream.wikimedia.org/v2/stream/recentchange" | ||
| 16 | local DEFAULT_LIMIT = 5 | ||
| 17 | |||
| 18 | -- shortens a long data payload for readable terminal output | ||
| 19 | local function preview(text, limit) | ||
| 20 | limit = limit or 100 | ||
| 21 | if #text > limit then return string.sub(text, 1, limit) .. "..." end | ||
| 22 | return text | ||
| 23 | end | ||
| 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 | ||
| 31 | local 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 | ||
| 42 | end | ||
| 43 | |||
| 44 | -- main program | ||
| 45 | arg = arg or {} | ||
| 46 | local url = arg[1] or DEFAULT_URL | ||
| 47 | local limit = tonumber(arg[2]) or DEFAULT_LIMIT | ||
| 48 | |||
| 49 | io.write("connecting to ", url, " (stopping after ", limit, " events)\n") | ||
| 50 | local ok, code = http.request{ | ||
| 51 | url = url, | ||
| 52 | headers_callback = sse.responseheaders(makeprinter(limit)) | ||
| 53 | } | ||
| 54 | |||
| 55 | if 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") | ||
| 58 | else | ||
| 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") | ||
| 63 | end | ||
