seanmonstar / reqwest

An easy and powerful Rust HTTP Client
https://docs.rs/reqwest
Apache License 2.0
9.67k stars 1.09k forks source link

WebSocket support #864

Open silvioprog opened 4 years ago

silvioprog commented 4 years ago

We love reqwest, but we also need to use websocket. :-)

Warp implements it at server-side, so it would be nice if reqwest could implement it at client-side allowing we to reuse all other features (e.g: TLS support) present in reqwest.

Cheers

seanmonstar commented 4 years ago

Curious, why would you use websockets outside a browser context?

x1957 commented 4 years ago

Some cryptocurrency exchange provide websocket API! ex. https://docs.pro.coinbase.com/#websocket-feed https://www.bitstamp.net/websocket/v2/ https://docs.kraken.com/websockets/

I'm using ws-rs, but it's not support async/await. It would be great if reqwest can support websocket!

silvioprog commented 4 years ago

Curious, why would you use websockets outside a browser context?

At the company, we are going to use websocket specially for sales terminal(s) monitoring, but there are many other features which websockets are useful outside a web browser, like real time gaming, embedded system remote control, industrial machine full-duplex communication via dedicated boards like STM32 and so on.

alexjg commented 4 years ago

Another use-case, the Kubernetes API server exposes a bunch of streaming stuff (e.g exec, port-forward) over websockets.

redradist commented 4 years ago

Is there any plan for support WebSockets ?

Yoric commented 3 years ago

Curious, why would you use websockets outside a browser context?

I need websockets for integration testing.

nicolaspernoud commented 2 years ago

It would be nice if reqwest supported websockets to allow reverse proxying of servers using websockets with something like https://crates.io/crates/warp-reverse-proxy like go reverse proxy does.

sgued commented 2 years ago

Given that reqwest is building support for WebAssembly for use in web context, supporting websockets in wasm could be a great ergonomics improvement over using web-sys manually.

xmo-odoo commented 2 years ago

Curious, why would you use websockets outside a browser context?

An other data point: Chrome's DevTools protocol uses bidirectional websockets as its baseline transport.

It also supports custom pipes but that's not really easy to do in rust, and obviously only works when the controller is also the creator of the chrome instance.

evklein commented 2 years ago

Curious, why would you use websockets outside a browser context?

I'm building a client side application which needs to maintain an established connection with a web server so the web server can periodically send some instructions back to the client machine. Doing this with websockes would greatly improve the experience.

rsalmei commented 1 year ago

Curious, why would you use websockets outside a browser context?

Like the above, I'm building an embedded client application, controlled remotely via events from another app. One can send commands there that are fetched by the client machines, but instead of polling every 5 or so seconds to see if there's any new event, I'd like to use websockets for faster delivery and near real-time processing.

hmeine commented 1 year ago

Is there any workaround ATM? I remember finding websocket client code that uses hyper.rs (but do not remember where right now), but apparently one also needs some additional crates (websocket? tokio-tungstenite?).

I am already using reqwest, so I was under the assumption that I should look for a hyper.rs solution, but maybe I should reconsider that? (I have not looked into what tungstenite even is yet, so maybe it's more compatible than I currently think.)

fredrik-jansson-se commented 1 year ago

I'm successfully using reqwest and tungstenite in the same project. Please ping if I can help with any info.

rakshith-ravi commented 1 year ago

I'm successfully using reqwest and tungstenite in the same project. Please ping if I can help with any info.

Would LOVE it if you could help us out with an example. Came here from Google and if we can have a gist (or even a comment with some example code, for that matter) that helps us understand how to use it, it would be super helpful

apqjd commented 1 year ago

무슨소리에요

apqjd commented 1 year ago

모르겠어요

fredrik-jansson-se commented 1 year ago

Of course, this is the code condensed that compiles:

use tokio_tungstenite::tungstenite::client::IntoClientRequest;

#[tokio::main]
async fn main() {
    let ws_url: url::Url = "wss://localhost".parse().unwrap();

    let tls = open_tls_stream(&ws_url).await;

    let (ws, _) = tokio_tungstenite::client_async(ws_url.into_client_request().unwrap(), tls)
        .await
        .unwrap();

    // Use ws object
}

async fn open_tls_stream(ws_url: &url::Url) -> tokio_native_tls::TlsStream<tokio::net::TcpStream> {
    let mut connector = tokio_native_tls::native_tls::TlsConnector::builder();

    // These certs should be shared between the reqwest and tungstenite clients
    let tls_ca: Vec<tokio_native_tls::native_tls::Certificate> = Vec::new();

    tls_ca.iter().for_each(|ca| {
        connector.add_root_certificate(ca.clone());
    });

    let connector = connector.build().unwrap();
    let connector: tokio_native_tls::TlsConnector = connector.into();
    let addrs = ws_url.socket_addrs(|| None).unwrap();
    let stream = tokio::net::TcpStream::connect(&*addrs).await.unwrap();
    let stream = connector
        .connect(ws_url.as_str(), stream)
        .await.unwrap();
    stream
}

For the actual code where I'm mixing reqwest and tungstenite, please see: https://gitlab.com/avassa-public/avassa-client-rs

And in particular: https://gitlab.com/avassa-public/avassa-client-rs/-/blob/main/src/volga/consumer.rs?ref_type=heads#L158 https://gitlab.com/avassa-public/avassa-client-rs/-/blob/main/src/lib.rs?ref_type=heads#L733

If this doesn't help or isn't what you're looking for, just comment here and I'll try to elaborate.

rakshith-ravi commented 1 year ago

I'll try using this and see how it goes. Thanks a lot for this! Really appreciate it

finnbear commented 9 months ago

Curious, why would you use websockets outside a browser context?

Calling AWS ApiGateway WebSocket endpoint from a server

jgraef commented 6 months ago

reqwest can do protocol upgrades, so I just went ahead and combined it with tungstenite. Here's the crate.