1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
-----------------------------------------------------------------------------
-- Server-Sent Events (SSE) demo client
-- LuaSocket sample files
--
-- Usage: lua sse.lua [<url>] [<event-count>]
-- Both arguments are positional and optional; with none given, connects to
-- a public live test feed and stops after 5 events.
-----------------------------------------------------------------------------
local http = require("socket.http")
local sse = require("socket.sse")
-- default target: Wikimedia's public, continuously-streaming recent-changes
-- feed -- a real, live text/event-stream endpoint, handy for trying out
-- socket.sse without standing up a server of your own
local DEFAULT_URL = "https://stream.wikimedia.org/v2/stream/recentchange"
local DEFAULT_LIMIT = 5
-- shortens a long data payload for readable terminal output
local function preview(text, limit)
limit = limit or 100
if #text > limit then return string.sub(text, 1, limit) .. "..." end
return text
end
-- builds a message callback that prints each received Message, then stops
-- the stream once "limit" of them have been printed. This module parses a
-- single request/response and never reconnects on its own (see
-- docs/adr/0001-sse-single-shot-no-auto-reconnect.md), so a caller who wants
-- to stop early just does what we do here: return an error from the
-- callback, which ends the request the same way any sink error would
local function makeprinter(limit)
local count = 0
return function(message)
count = count + 1
io.write(string.format("[%d] event=%s id=%s\n data=%s\n",
count, message.event, tostring(message.id), preview(message.data)))
if count >= limit then
return nil, string.format("stopped after %d events", limit)
end
return 1
end
end
-- main program
arg = arg or {}
local url = arg[1] or DEFAULT_URL
local limit = tonumber(arg[2]) or DEFAULT_LIMIT
io.write("connecting to ", url, " (stopping after ", limit, " events)\n")
local ok, code = http.request{
url = url,
headers_callback = sse.responseheaders(makeprinter(limit))
}
if ok then
-- the server closed the connection on its own before we hit our limit
io.write("connection closed by server, code=", tostring(code), "\n")
else
-- once the callback above returns an error, http.request reports it the
-- same way it reports any failure: (nil, message) -- so "code" here is
-- really our own "stopped after N events" message, not a real error
io.write(code, "\n")
end
|