snapview / tungstenite-rs

Lightweight stream-based WebSocket implementation for Rust.
Apache License 2.0
1.87k stars 215 forks source link

Regarding tungstenite’s support for packet capture tools #406

Closed zsl99a closed 8 months ago

zsl99a commented 8 months ago

First of all, thank you all for providing such a powerful websocket tool.

I am now trying to use charles to observe tungstenite traffic, but after several attempts, they all failed. My system environment is macOS m1 14.3, and the charles certificate is correctly configured. According to the current conclusion: the https and wss links of the firefox browser and the http(s) of the rust reqwest library can be recognized normally, but the tungstenite traffic is not recognized. Based on my shallow knowledge, I guess it is caused by a certain websocket standard being ignored. I'm now forced to use tracing for observations. But in my business scenario, I need to connect to a large number of websocket servers to obtain data for summary analysis. So logging doesn't seem to be a very convenient way to debug. If this problem can be solved or provide some guidance on how I can solve this problem. I believe it will bring some help to the debugging experience during the development process. I will be very grateful. I wish you all a wonderful life.

Here are the two test codes I used:

    let (mut stream, _resp) =
        async_tungstenite::tokio::connect_async("wss://...")
            .await?;

    while let Some(Ok(msg)) = stream.next().await {
        match msg {
            Message::Text(text) => {
                println!("{}", text);
            }
            _ => {}
        }
    }

and

    let (mut stream, _resp) = tungstenite::connect("wss://...")?;

    while let Ok(msg) = stream.read() {
        match msg {
            Message::Text(text) => {
                println!("{}", text);
            }
            _ => {}
        }
    }
zsl99a commented 8 months ago

After several hours of hard work. I found a temporary solution, this issue seems to be somewhat related to #177

use std::error::Error;

use async_tungstenite::tungstenite::{handshake::client, Message};
use futures::StreamExt;
use tokio_socks::tcp::Socks5Stream;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let socks_stream = Socks5Stream::connect("127.0.0.1:8889", "fstream.binance.com:443").await?;

    let mut request = client::Request::builder().uri("wss://fstream.binance.com/ws/btcusdt@trade").body(())?;
    request.headers_mut().insert("Host", "fstream.binance.com".parse()?);
    request.headers_mut().insert("Sec-WebSocket-Protocol", "chat, superchat".parse()?);
    request.headers_mut().insert("Sec-WebSocket-Version", "13".parse()?);
    request.headers_mut().insert("Sec-WebSocket-Key", client::generate_key().parse()?);
    request.headers_mut().insert("Upgrade", "websocket".parse()?);
    request.headers_mut().insert("Connection", "Upgrade".parse()?);

    let (mut stream, _) = async_tungstenite::tokio::client_async_tls(request, socks_stream).await?;

    while let Some(Ok(msg)) = stream.next().await {
        match msg {
            Message::Text(text) => {
                println!("{}", text);
            }
            _ => {}
        }
    }

    Ok(())
}
daniel-abramov commented 8 months ago

Sorry, I don't quite get what you mean by

the https and wss links (..) are recognized normally, but the tungstenite traffic is not recognized

Recognized by whom and in which way? The first sample code - what was the result of its execution?

As for the latest snippet: ok, I see, so your setup requires connecting via a proxy first, right? - If so, then your assumption is correct we indeed do not provide a "built-in" support for the socks.