You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Tungstenite连接Binance Websocket API遇400错误的原因排查

连接Binance WebSocket遇到400错误的问题与解决

问题描述

我尝试使用Rust的tungstenite库连接Binance WebSocket服务器,相关代码、依赖配置及报错信息如下:

连接代码

use tungstenite::{connect, Message};
use url::Url;

fn main() {
    let (mut socket, response) =
        connect(Url::parse("wss://stream.binance.com:9443/ws/BNBBTC@aggTrade").unwrap()).expect("Can't connect");

    println!("Connected to the server");
    println!("Response HTTP code: {}", response.status());
    println!("Response contains the following headers:");
    for (ref header, _value) in response.headers() {
        println!("* {}", header);
    }
}

Cargo.toml依赖配置

[dependencies]
tungstenite = "0.17.3"
url = "2.3.1"

报错信息

thread 'main' panicked at 'Can't connect: Http(Response { status: 400, version: HTTP/1.1, headers: {"server": "awselb/2.0", "date": "Sat, 22 Oct 2022 20:23:40 GMT", "content-type": "text/html", "content-length": "220", "connection": "close"}, body: None })', src/main.rs:6:90
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/core/src/panicking.rs:142:14
   2: core::result::unwrap_failed
             at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/core/src/result.rs:1814:5
   3: core::result::Result<T,E>::expect
             at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/core/src/result.rs:1064:23
   4: untitled12::main
             at ./src/main.rs:6:9
   5: core::ops::function::FnOnce::call_once
             at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/core/src/ops/function.rs:248:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

根据Binance官方WebSocket API文档,请求格式应该合规,请问错误原因是什么?遗漏了哪些内容?


错误原因与修复方案

错误原因

400错误是因为tungstenite 0.17.3版本的connect函数在构建WebSocket握手请求时,没有自动添加正确的Host请求头,而Binance的WebSocket服务器对请求头的完整性有严格要求,缺少Host头会被判定为无效请求,直接返回400错误。

修复方案

有两种可行的解决方式:

方式一:手动添加Host请求头

通过tungstenite::client::IntoClientRequest自定义握手请求,手动插入Host头:

use tungstenite::{client::IntoClientRequest, connect, Message};
use url::Url;

fn main() {
    let url = Url::parse("wss://stream.binance.com:9443/ws/BNBBTC@aggTrade").unwrap();
    
    // 构建自定义请求并添加Host头
    let mut request = url.into_client_request().unwrap();
    request.headers_mut().insert(
        "Host",
        "stream.binance.com:9443".parse().unwrap(),
    );
    
    let (mut socket, response) = connect(request).expect("Can't connect");

    println!("Connected to the server");
    println!("Response HTTP code: {}", response.status());
    println!("Response contains the following headers:");
    for (ref header, _value) in response.headers() {
        println!("* {}", header);
    }
}

方式二:升级tungstenite版本

新版本的tungstenite(0.20+)会自动处理Host头的正确设置,无需手动配置。修改Cargo.toml的依赖版本:

[dependencies]
tungstenite = "0.20.0"
url = "2.3.1"

验证说明

Binance的WebSocket服务器需要握手请求包含正确的Host头部,以确保请求被路由到正确的端点。采用上述任一方式后,即可正常建立WebSocket连接。


内容的提问来源于stack exchange,提问作者avernus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 00:41:38