what is the purpose of the :expose-api-at
key in pedestal vase?
https://github.com/cognitect-labs/vase/blob/7beba1e549a79166be5e73dd7714edb4e9b9d3e9/samples/petstore/petstore.fern#L25
it doesn't seem to be used anywhere
I'm trying to get my head round WebSockets on the Server side (jetty)
The simple onTextMessage
callback provides no context about which connection sent the message
https://github.com/eclipse/jetty.project/blob/923ec38adf64d1d68da6a91902f5925a8bffb7d9/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/events/EventDriver.java#L65
how do people normally corrrelate incoming messages with a specific clent connecttion?
I'm hopinig I can create a UUID session key that I can close over a new ws-listener map sort of thing but its not quite clear how to proceed
I could contrive that every message contained information to identtify its owner, but am hoping that is not necessary
WebSocketAdapter just hangs onto the Session object that was presented to it originally, and doesn't worry about cross talk so perhaps I can do something like that https://github.com/eclipse/jetty.project/blob/e3c8546667aca1ee0247dfc4154a6e7189a23c81/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketAdapter.java#L28
@ben.hammond Funny how I had the exact same question few days back. The solution is as you said, supply your own listener to Pedestal as :listener-fn
.
(defn ws-listener
[_request _response ws-map]
(proxy [WebSocketAdapter] []
(onWebSocketConnect [^Session ws-session]
(proxy-super onWebSocketConnect ws-session)
(when-let [f (:on-connect ws-map)]
(f ws-session)))
(onWebSocketClose [status-code reason]
(when-let [f (:on-close ws-map)]
(f (.getSession this) status-code reason)))
(onWebSocketError [^Throwable e]
(when-let [f (:on-error ws-map)]
(f (.getSession this) e)))
(onWebSocketText [^String message]
(when-let [f (:on-text ws-map)]
(f (.getSession this) message)))
(onWebSocketBinary [^bytes payload offset length]
(when-let [f (:on-binary ws-map)]
(f (.getSession this) payload offset length)))))
::http/container-options {:context-configurator #(ws/add-ws-endpoints % ws-paths {:listener-fn ws-listener})}
https://github.com/sunng87/ring-jetty9-adapter/blob/master/src/ring/adapter/jetty9/websocket.clj#L95
https://github.com/pedestal/pedestal/blob/master/jetty/src/io/pedestal/http/jetty/websockets.clj#L104lovely thankyou I was looking for some affirmation
although
I'm wondering if it could be simpler than that
If I write this as my listener function
(defn ws-stateful-listener
[^ServletUpgradeRequest req
^ServletUpgradeResponse resp
wsmap-genfn]
(ws/make-ws-listener (wsmap-genfn (UUID/randomUUID))))
and then I close over that UUID in the ws-map
and use it as a key into my ws-sessions atomits not quite as tidy as yours, because I've had to invent a new synthetic key where the WebSocketSession would have done just as well but its a wee bit less upfront code
Yeah, I know where you are coming from. The default listener provided by Ring Jetty9 Adapter is way more useful. The Pedestal one, not so much. I am not an expert so can't comment on which way is better.
@ben.hammond I think the intent was to leverage that to specify the api entry point but was not implemented. I’ll make a note to look into it and clean it up.