pedestal

2020-04-09T07:58:19.057400Z

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

2020-04-09T13:25:02.057700Z

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?

2020-04-09T13:28:47.059Z

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

2020-04-09T13:41:22.059900Z

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

2020-04-09T13:44:41.060900Z

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

hindol 2020-04-09T13:58:44.062200Z

@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#L104

👍 1
2020-04-09T16:36:50.063100Z

lovely thankyou I was looking for some affirmation

2020-04-09T16:37:57.063600Z

although

2020-04-09T16:38:12.064Z

I'm wondering if it could be simpler than that

2020-04-09T16:40:57.065200Z

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 atom

2020-04-09T16:42:23.066800Z

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

hindol 2020-04-09T16:51:59.068300Z

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.

2020-04-09T17:23:55.068400Z

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

👍 1