Hi! Using websocket-client
to connect into websocket endpoint. This works just fine but I have a problem when target endpoint is not there when trying to make the connection
The connection creation just hangs forever, no errors or anything
I must be missing something
I think it is because websocket-client
returns a deferred which I must first dereference to use it
And that dereferencing will hang until the connection is established, which it never manages to do since the target endpoint isn't available
So, is there a way to tell the websocket-client
a connection timeout?
First, you can use (d/timeout _)
to fail the deferred after timeout you need
OK, that was what I was more or less looking for I think
Second, there’s a ConnectionTimeout that fires when you cannot establish a TCP connection. The problem with Websocket protocol is that it requires one another round-trip to setup the stream: handshake request/response (see https://github.com/ztellman/aleph/pull/422 and https://github.com/netty/netty/issues/8841). If your server is “not there”, it fails. If your server unable to finish the handshake - it’s not managed by the Aleph for now (it would be after PR is merged tho’).
Right
Well in this case the target server is starting sometimes when I'm trying to establish connection
And it will get up eventually
(or if it doesn't then there's a bigger problem)
(-> (websocket-client ...)
(d/timeout! 5e3 ::timeout)
(d/chain' (fn [conn] (if-not (identical? ::timeout conn) conn (time/in 5e3 (websocket-client ...))))))
Out of my head, didn’t test it 🙂
hehe
TCP doesn’t have a solution for “server is starting” as a protocol, unfortunately 😉
Yeah I know
It is pretty obvious that I need to retry a bit later if it isn't just there
And do that for x times or give up
Correct
Hi! There is a lot of middleware for the HTTP client. Yet I don’t understand how to use them when sending HTTP calls. For example, when GET-ting a JSON file, how to finish with the body being parsed automatically? What option should I specify?
What I’ve tried:
@(http/get "<https://blockchain.info/latestblock>")
returns just a byte stream as body@(http/get "<https://blockchain.info/latestblock>"
{:middleware middleware/wrap-request})
gives the same resultWrap-request is applied automatically
:as :json should work
let me try
what works! Does it mean, I can just pass the standard clj-http args?
Almost always :)
There’s a list of those things that are different
In README
when sending JSON body, with that work?
:form-params {:foo 42}
:content-type :json
Yep
Or :application/json
I don’t remember exactly
yes, it seems to be the full version
(defmethod coerce-form-params :application/json
What about clj-http? Do they accept short version?
yes, the take just :content-type :json
Feel free to open an issue with “clj-http parity” tag :)
Or I’ll do that in the evening
but it’s not a problem, really. Instead, it would be nice to add more examples in readme because auto encode/decode JSON happens constantly
ok probably I’ll contribute
what is good about clj-http, you never remember all the options, but they’ve got rich base of examples, so you just copy and paste
Let me know if I can help with anything
The idea was that you can just copy example for clj-http and it works 😂
But, yeah... documentation is a weak point for now
And it requires constant attention
maybe I was confused with a docstring to aleph.http/request
function which highlights only the basic args
but it’s clear now, thanks a lot!
My pleasure!