This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-08-08
Channels
- # architecture (8)
- # beginners (78)
- # boot (20)
- # cider (81)
- # clara (53)
- # cljdoc (10)
- # cljsjs (3)
- # clojure (55)
- # clojure-boston (1)
- # clojure-dev (25)
- # clojure-nl (3)
- # clojure-uk (65)
- # clojurescript (65)
- # core-async (1)
- # cursive (41)
- # data-science (4)
- # datomic (16)
- # editors (74)
- # emacs (17)
- # events (1)
- # figwheel (3)
- # hyperfiddle (39)
- # immutant (16)
- # jobs-discuss (62)
- # juxt (2)
- # keechma (2)
- # leiningen (6)
- # mount (7)
- # nrepl (1)
- # off-topic (30)
- # onyx (14)
- # protorepl (2)
- # re-frame (4)
- # reagent (15)
- # reitit (19)
- # shadow-cljs (102)
- # sim-testing (1)
- # spacemacs (44)
- # specter (15)
- # tools-deps (50)
- # vim (2)
Hi all. I'm trying to use some Server Sent Events with immutant.web.sse/send!
, but I'm not sure that what it's sending is entirely conformant with the spec: https://www.w3.org/TR/eventsource/. For example if I send {:data "YHOO\n+2\n10"}
in attempt to emulate an example in the spec, I believe I should receive three data:
lines in the SSE receiver, but instead what is being delivered is the following sequence of lines:
"data:YHOO"
"+2"
"10"
""
However this is not conformant. According to the spec the "+2"
and "10"
lines would be interpreted as field names, and corresponding values would be empty strings. What is the proper immuntant way to send multi-line data in an event? And is the above a bug? I think so.I could be misinterpreting the spec, I'm still looking at it, and trying to get a decent clojure SSE client to process SSE streams. Some of the ones I've looked at spend more time dwelling on use of clojure.core.async than on correctness of SSE client stream processing.
Hmmm, I'm guessing immutant.web.async/send!
calls wil let me send a conformant message, but it's a pity immutant.web.sse/event->str
doesn't do the right thing. Or have I got it all wrong? Anyway, suggestions/corrections welcome. From my perspective there is a documented protocol for SSE data transmission and ideally immutant's SSE send should conform to it if it wants conformant clients (such as web browsers and EventSource implementations) to work. If I develop any patch-worthy code I'll submit it, assuming I even have a clue, I'm new to SSE. I have an API that uses immutant SSE for select service calls, and clojure (not clojurescript) client processes that are subscribing to those SSE channels.
So (event->str {:data ["abc" "def"]}) => "data:abc\ndata:def\n"
is close, what we probably want is a method on the Event protocol for strings that splits them based on newlines (or CR/CRLF) to generate multiple data: elements.
It's been a long time since I looked at the sse code, but I recall that the intention was that if you wanted to send multiple data lines, you send a sequence: {:data ["line1" "line2" "line3"]}
But it probably makes sense to also support raw strings, and do the right thing with them in event->str
It's fine if your data is already split into vectors, and "close" is because I was unsure when I wrote it (i.e. I wasn't sure).
(extend-protocol immutant-sse/Event
String
(immutant-sse/event->str [str] (clojure.string/join "\n" (mapv (fn [s] (str "data:" s)) (clojure.string/split str #"(?:\r\n)|\r|\n")))))
That split/join logic will take a string with cr/lf/crlf terminated lines and break them up, including empty lines so that you still get data:\n
where appropriate