-
Notifications
You must be signed in to change notification settings - Fork 787
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add client support for websockets #330
Comments
As a start to getting this discussion rolling, is there a reasonable situation where a websocket client won't behave almost completely different than a regular client? Besides giving it a Url, and of course that fact that websocket is bootstrapped on a http request, it seems to me like they would be very different concepts. |
Should the API look something like this?
|
As with the server, I think we want to give the client an |
But isn't the initial connection a typical http request that gets upgraded? I am not sure I understand in what way the above example code does not give the client an |
In your example you've clearly transformed the body into an Under the covers a websocket request starts as a http request, but your example above will fail due to not including an |
Okay, I understand your point better now. Do you think it would be acceptable to add the headers As for the |
Given that For instance, I am also concerned about potentially needing to modify http4s-websocket to add support for the client and having that be a bad workflow. |
blaze, not to be confused with http4s-blaze-core, uses http4s-websocket. It was spun off from blaze so http4s-servlet can eventually use it. |
Okay, I am a little confused, but if it's necessary. It's unfortunate though that we need to dumb down the APIs. |
Think of blaze and http4s-websocket as completely unaware of http4s. (Which makes the "http4s-websocket" name pretty unfortunate. Hmm.) Things that make sense for websockets as a wire protocol belong in http4s-websocket. Things that make sense for websockets in conjuncton with the http4s model belong in http4s-core. API for the client and server belong in http4s-client and http4s-server, respectively. So:
|
@rossabaker That makes sense. I would argue though that if websockets deserves it's own library that defines websocket concepts in a very abstract way, that it might make sense for HTTP to get the same treatment, a library that defines things like headers, response codes, media formats, etc in an abstract way, with nothing to do with scalaz-stream and such. And if that were the case, it might make sense to have websockets depend on http. |
@bryce-anderson I re-read your comment this morning (way above) about the API "running" the Maybe that is the right approach, but I am not convinced. Such an approach would suffer from the same problem that the server side API for websocket suffers, that is, the necessity for the user to instantiate a queue to accomplish simple things (which I continue to believe is undesirable). Let's say we have the following:
My belief is the above scenario should be fairly common. This is what it looks like with an API that requires supplying an
This is what it looks like if the API provides an
Does this seem reasonable? This was partly an exercise for myself but I hope it is useful to the discussion. |
On another note, to answer your original question @bryce-anderson, it is very true that a websocket client does not appear to share all that many things with a regular HTTP client. That being said, I think it would be nice to share the functionality around connection pooling if at all possible. |
Just reading up on this, I was wondering what is the best way to consume a webSocket from an http4s client right now? |
There isn't currently a way to do so. I started something in #618, but haven't made time to finish it. Perhaps someone would like to pick that up and run with it? |
It could be related to #1051 |
is this nearing completion by any chance? |
@AnirudhVyas today I've learned that in fact there is a WebSocket client in http4s project: https://jdk-http-client.http4s.org/latest/index.html#websocket-client |
Yes, we are using it in kubernetes-client. |
I haven't heard objections to the existing client interface. It would be great to get that moved into core and a second implementation, if someone is looking for a medium-effort contribution. |
@rossabaker I would like to take this, if it's not urgent. |
@nelusnegur Do you have a backend in mind that you'd like to try to implement it on? AHC, okhttp, and Jetty all have their own models for it. Ember would be pure FP, but have more from-scratch coding. Blaze has the same drawbacks as Ember, and also gets you into Futureland. |
@rossabaker I haven't thought about it yet, but from your short summary, I would prefer Ember (I'll have a longer journey, but a more interesting one). |
@amesgen has done most of the work on web sockets and @ChristopherDavenport on Ember, so I suggest we invite their wisdom. I would think any client interface belongs in You might want to focus on client support first, since that's been in high demand for a while, and there's currently no option before JDK11. Then server support could be added to ember in a followup. |
Websocket is sorta an upgrade protocol where its just never released right? In which case you have the socket, so if we know its a websocket, then should be pretty operable. The client is definitely simple, as you can almost immediately pull out a connection and then turn that into the protocol fairly independently of the rest of the flow, steal the internals as helpers as necessary. My knowledge of websockets is the part thats not super helpful here. Buts once you have a socket everything is fairly straightforward byte protocols. |
I can't remember without looking whether a web socket connection can be returned to the pool for HTTP after the close handshake, or whether a termination of the connection is part of the protocol. But implementing as the latter would at least get things off the ground, I think. |
https://github.com/http4s/http4s/blob/master/ember-client/src/main/scala/org/http4s/ember/client/internal/ClientHelpers.scala#L52 - This is presently how we extract out a request socket. It forms the basis of its extraction from the pool inside the builder. Then its actually just the client operating with that taken resource which is a RequestKeySocket, which is just a socket with a request key so we know how to reuse. So if we need to change creation that would be that first helper, but otherwise you then have a socket and can implement a protocol fully independently. The client is straight forward. Get connection from pool, log state, run the request through the |
Thank you all very much for the explanations! That was really helpful. I'll try to implement the client first, and then we can move forward to server side part. |
Hi. I wanted to let you know that I'm not able to work on this issue anymore. I thought I'll have time during the weekends, but due to some personal circumstances, currently I cannot find the necessary time for it. I'm really sorry about this. Thank you so much for the opportunity to contribute! |
Thanks for the update. I hope things turn out well, and if you have time again in the future, I'm sure we'll have more work! |
Let's at least assure ourselves we can do this in a non-breaking way before going 1.0. This is one of the highest value tickets on the board. |
Done in #5520. |
It is currently possible to implement a server that exposes a websocket endpoint. However we currently do not provide support for consuming websockets through the client.
The text was updated successfully, but these errors were encountered: