I know ring server will close a WebSocket connection after a Connection Idle Timeout amount of time which is 30 seconds.
And I have read that the load balancers etc will override this value by their specific value. So especially in production there will be one and my ring config for this will not matter. It will matter on dev whenI do not have another server in the front.
I have seen in ring version 1.14.1 added a jetty option for :ws-idle-timeout.
CHANGELOG: https://github.com/ring-clojure/ring/blob/master/CHANGELOG.md#1140-2025-03-25
I have passed it to jetty/run-jetty but nothing has changed? How to use this option? (With a longer idle timeout I could have to send less frequent pongs with ring.websocket.keepalive I am using.
Can you explain how you're currently using it? Perhaps there's something you're doing incorrectly. That option does have a test, so it should be working.
I'd also like to direct your attention to https://github.com/ring-clojure/ring-websocket-middleware which has a ring.websocket.keepalive middleware function for automating ping/pong keepalives.
This is also included in the latest version of Ring-Defaults: https://github.com/ring-clojure/ring-defaults
And on the subject of recommended libraries, you might also want to look at: • https://github.com/ring-clojure/ring-websocket-async • https://github.com/ring-clojure/ring-websocket-transit This is unrelated to your question, but these are libraries I always use in conjuction with websockets.
I have tried using :ws-idle-timeout like below:
(defn start-server [port]
(reset! server
(jetty/run-jetty (wrap-reload #'request-handler)
{:port (Integer. port)
:join? false
:ws-idle-timeout 60000
:ssl? true
:ssl-port 443
:keystore "keystore.jks"
:key-password "password"
:sni-host-check? false
})))
But connection is closed for idleness after 30 seconds. [ring “1.14.1”]
Thanks for the extra directions.Can you check lein deps :tree to ensure that you're using the latest ring/ring-jetty-adapter dependency? Sometimes you can end up with older dependencies by accident due to the way dependency resolution works in Lein/Maven.
Another possibility is that the client has a 30s timeout.
I have restarted the server and run lein deps tree: ring entry is at 1.14.1. Now it cannot find ring.middleware.params so I cannot retest. Maybe newer versions had breaking changes, but not sure as I could not see it in change log.
I was using ring 1.13.0 before
There are no breaking changes to Ring (at least not since 1.0.0).
Maybe try lein clean? It sounds like something's going wrong if it can't find the params middleware.
Also, just to be clear: it's the ring/ring-jetty-adapter dependency specifically that needs to be 1.14.1. It's very possible for ring to be 1.14.1, but for its subdependencies to be different versions, if other libraries also depend on Ring.
In my project.clj I only have these deps:
:dependencies [[org.clojure/clojure "1.11.1"]
[ring "1.14.1"]
[ring/ring-ssl "0.4.0"]
[org.ring-clojure/ring-websocket-middleware "0.2.1"]
[compojure "1.7.1"]
[org.clojure/java.jdbc "0.7.12"]
[org.postgresql/postgresql "42.7.5"]
[hiccup "1.0.5"]
[buddy/buddy-sign "3.5.351"]
not a separate ring/ring-jetty-adapterhow should a proper deps setup should look like?
my requires are this now:
[ring.adapter.jetty :as jetty]
[ring.websocket :as ws]
[ring.websocket.keepalive :refer [wrap-websocket-keepalive]]
[ring.middleware.ssl :refer [wrap-ssl-redirect]]
[ring.middleware.reload :refer [wrap-reload]]
[ring.middleware.params :refer [wrap-params]]
[ring.middleware.resource :refer [wrap-resource]]
[ring.middleware.file-info :refer [wrap-file-info]]
[ring.middleware.content-type :refer [wrap-content-type]]
[ring.middleware.not-modified :refer [wrap-not-modified]]
[ring.handler.dump :refer [handle-dump]]
[compojure.core :refer [defroutes GET POST PUT PATCH DELETE ANY]]
[compojure.route :as route]
#_[buddy.auth :refer [authenticated?]]
#_[buddy.auth.middleware :refer [wrap-authentication]]
[buddy.sign.jwt :as jwt]))Yes, that should be fine. The thing to be cautious about is that Leiningen (and Maven) resolve "nearest" dependencies first. So Compojure is at distance 0, because you've directly included it. Ring is also at distance 0, but Ring includes ring/ring-core, ring/ring-jetty-adapter, etc. And these would be at distance 1, since they're 1 step removed.
So if, say, Compojure relies on an older Ring library, that would also be at distance 1. It might be that Compojure's dependencies override Ring's dependencies. It's for this reason it's useful to use lein deps :tree to ensure that there are no dependency conflicts.
lein deps :tree | grep ring yields:
Possibly confusing dependencies found:
[compojure "1.7.1"] -> [ring/ring-codec "1.2.0"]
overrides
[ring "1.14.1"] -> [ring/ring-core "1.14.1"] -> [ring/ring-codec "1.3.0"]
Consider using these exclusions:
[ring "1.14.1" :exclusions [ring/ring-codec]]
😄
Looks like Just what you have said
It looks like only ring-codec was affected, which wouldn't impact the :ws-idle-timeout option. You can fix that just by including the latest ring-codec version as a direct dependency.
ring-codec would affect wrap-params issue I guess
Yes, that's possible... Perhaps the namespace failed to load due to being unable to find a function in ring-codec.
I'm unsure why the idle timeout isn't working for you, though. The test only checks for lowering the idle timeout (since waiting for 60s every test would take too much time), so it's possible 30s is a maximum. However, I'm almost certain I tested a 60s timeout manually, as that was something I specifically wanted to do.
If you can create an example project that replicates the issue, and eliminate the possibility of it being a client-side timeout, then please open an issue on the Ring repository.
To avoid these exclusions etc here and there shoud l jsut install ring/ring-jetty-adapter separately to haev new ws-idle-conenction options and do not affect the rest?
Since ring-jetty-adapter wasn't listed as a conflict, it should be fine. However, putting it in your dependencies can't hurt, and might eliminate issues in future.
if I do that should I separately ad the ring-core too. And where does all the middleware comes from with ring.middleware like namespaces. Or should I have just ring 1.13.1 in the deps and the ring-jetty-adapter 1.14.1. I will give it a try.
The middleware comes from ring-core for the most part. You only need to worry about dependencies if lein deps :tree reports a conflict. If lein deps :tree says everything is okay, then you're fine.
it complains much more Possibly confusing dependencies found: than before now. I do not want this to be like a nodejs deps issue :D
If it does not complain much I guess I will be ok without new :ws-idle-timeout option.
yes, ring “1.13.0” and no confusions at all.
Thank you very much for your help
Ring 1.13.0? You mean 1.14.1?
Ideally you should use the latest versions. If Compojure is using an older version of Ring-Codec, then add the newer version of Ring-Codec to your dependencies to resolve it.
So this is how your dependencies should look:
:dependencies [[org.clojure/clojure "1.11.1"]
[ring "1.14.1"]
[ring/ring-codec "1.3.0"]
[ring/ring-ssl "0.4.0"]
[org.ring-clojure/ring-websocket-middleware "0.2.1"]
[compojure "1.7.1"]
[org.clojure/java.jdbc "0.7.12"]
[org.postgresql/postgresql "42.7.5"]
[hiccup "1.0.5"]
[buddy/buddy-sign "3.5.351"]]
I just tested them in a project, and there are no dependency conflicts with that.Yes, I have tried your solution above and lein deps :tree shows no confusions.
And wrap-params is found too.
Great new :ws-idle-timeout option works for me too. And now I need to send only 55 seconds period pongs with the related package and that will be enough. Or set a value and pass it to the :ws-idle-timeout option and one lesser than this like 5 seconds to calculate the one I pass the to the pong period.
Thank you very much for your help!