Fork me on GitHub
Ben Hammond07:04:19

what is the purpose of the :expose-api-at key in pedestal vase? it doesn't seem to be used anywhere


@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.

👍 4
Ben Hammond13:04:02

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 how do people normally corrrelate incoming messages with a specific clent connecttion?

Ben Hammond13:04:47

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

Ben Hammond13:04:22

I could contrive that every message contained information to identtify its owner, but am hoping that is not necessary

Ben Hammond13:04:41

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


@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})}

👍 4
Ben Hammond16:04:50

lovely thankyou I was looking for some affirmation

Ben Hammond16:04:12

I'm wondering if it could be simpler than that

Ben Hammond16:04:57

If I write this as my listener function

(defn ws-stateful-listener
  [^ServletUpgradeRequest req 
   ^ServletUpgradeResponse resp 
  (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 atom

Ben Hammond16:04:23

its 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.