Росен Христов (Rossen Hristov)
unread,Mar 27, 2024, 1:02:52 PM3/27/24Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to pedestal-users
Hello,
I am working on an application that used to use websockets but due to scaling issues with them, we decided to replace them with server-sent events (SSE).
Our goal is to make it possible to create an SSE channel for every successfully logged user in order to be able to close this channel after user logout or session timeout in order not to consume unnecessary resources by unused channels remaining opened after the given user is logged out. These user channels we store in an atomic map registry and want to access the channel of the specific logged user (recognized by its session token used as a key in the registry) to send the messages to the frontend.
We used initally the io.pedestal.http.sse namespace but the problem with it is that it expects the handler to accept a "default" channel as route handler input argument:
and if I try to use the separate user channel the messages are not received, for example in Postman I get empty response, the response contains the expected messages only if you rely on te default channel that the handler gets as input aregument:
This the route using
start-event-stream which returns an interceptor that uses the handler whenever a message has to be sent:
(defn sse-handler [channel ctx]
...)
This is the route:
(def sse-route ["/rest/sse" :get (sse/start-event-stream sse-handler)
:route-name :sse])
This is the handler:
(defn sse-handler [channel ctx]
(doseq [[id {:keys [name data] :as payload}] @LIVE-NOTIFICATIONS]
(when-not (chan/closed? channel)
(async/>!! channel payload)
(swap! LIVE-NOTIFICATIONS dissoc id)
(Thread/sleep 1000)))
(async/close! channel))
My question is: Is it possible to implement such a scenario using the individual user channel not the input one coloured in red above and how? Do I have to implement my own custom interceptor or I still can use the
io.pedestal.http.sse ns somehow?Or if I have to use the input argument channel is it possible for example to access it somehow to close it when the user is logged out?
Thank you in advance for the help!
Rossen Hrisrov