Hey folks 👋 I’m using the Kit framework and trying to add a Server-Sent Events (SSE) endpoint. I know SSE isn’t supported natively, but Undertow has a built-in ServerSentEventHandler that I’d like to use.
I’ve written a sse-ring-handler that sets the right headers and tries to hand off to a ServerSentEventHandler instance. The route (`["/events" {:get (fn [req] (sse-ring-handler (:server-exchange req))}]`) does get hit, but the actual Undertow handler doesn’t seem to run.
The ServerSentEventHandler has a handleRequest method that expects a HttpServerExchange, and I’m not sure how to properly invoke or wire that into the Kit/Integrant setup. I think I might be missing a key step in letting Undertow take over the request.
Any pointers or examples would be super appreciated!
Thanks 🙏
The https://github.com/starfederation/datastar/tree/develop/sdk/clojure/adapter-ring is actually generic, it makes use of the StreamableResponseBody protocol. In theory any ring adapter handling this protocol properly should work. Right now it is tested with the ring Jetty adapter and Rj9a. Rj9a only works partially with the datastar SDK though, there is an issue at the moment where it closes http connections in async mode when it shouldn't.
I see. I'd better try again setting up for Undertow alone and see if it could possibly work. I think undertow adapter comes with kit, but I hope I can use it standalone as well. By the way, thanks for making Clojure SSE plugin available for Datastar.
You're welcome! If the current undertow adapter doesn't use the StreamableResponseBody properly and you want to use the Datastar SDK we https://github.com/starfederation/datastar/blob/develop/sdk/clojure/doc/implementing-adapters.md beyond the source code to help you make your own SDK adapter. Good luck!
Your handler doesn't actually pass the request down - it just returns the sse-ring-handler function. I don't know anything about Kit, so maybe it has some middleware that calls functions that were returned from a handler. But if that's not the case, you should be calling that function yourself.
Thanks! I realize this might have been a bit confusing on my part — the code was just meant as an example. What I’m really stuck on is how to pass an HttpServerExchange to the Undertow handler. I’m not sure how to wire that into the route properly.
I updated the example
I don't know if this is the case but if your ring undertow adapter is compliant with / uses the ring.core.protocols/StreamableResponseBody protocol you can implement it and manage a SSE connection from there.
https://github.com/starfederation/datastar/tree/main/sdk/clojure Not sure if this would help you somehow. The above is SSE plugin provided by datastar. They work for Jetty and Http-kit. But sadly, doesn't work for undertow. So I have to switch to either http-kit or jetty with Kit. (Note: I am also using Kit web framework and datastar).