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

如何在Rust中实现可正常运行的WebSocket客户端?

问题根因分析

  • 第一段代码错误使用了listen方法:ws库的listen是用于启动WebSocket服务端监听端口的API,实现客户端应该调用connect方法,这是最核心的错误。
  • 第二段代码的发送时机错误:直接在connect的入参闭包里执行发送逻辑,此时WebSocket连接还未完成握手,on_open回调还没触发,消息发不出去也不会报错,连接握手完成后自然也不会再执行你的发送逻辑。
  • 缺少TLS支持:你要连接的是wss开头的加密WebSocket地址,默认的ws库没有开启TLS feature,需要在Cargo.toml里开启对应的依赖配置。

修复步骤

首先修改Cargo.toml依赖配置,开启TLS支持:

[dependencies]
ws = { version = "0.9", features = ["ssl"] }

Handler写法修复版

extern crate ws;

use ws::{connect, Handler, Sender, Handshake, Result, Message};

struct Client {
    out: Sender,
}

impl Handler for Client {
    fn on_open(&mut self, _: Handshake) -> Result<()> {
        // 连接握手完成后再发送认证和监听请求
        self.out.send(r#"{"action": "authenticate","data": {"key_id": "<API_KEY>","secret_key": "<API_SECRET>"}}"#)?;
        self.out.send(r#"{"action": "listen","data": {"streams": ["AM.SPY"]}}"#)
    }

    fn on_message(&mut self, msg: Message) -> Result<()> {
        println!("message: {}", msg);
        Ok(())
    }

    fn on_error(&mut self, err: ws::Error) {
        // 加上错误回调方便排查问题
        eprintln!("WebSocket error: {:?}", err);
    }
}

fn main() {
    // 客户端用connect,不要用listen
    if let Err(error) = connect("wss://data.alpaca.markets/stream", |out| {
        Client { out }
    }) {
        println!("Failed to create WebSocket due to: {:?}", error);
    }
}

闭包写法修复版

如果你偏好闭包写法,修复后的代码如下:

extern crate ws;

use ws::{connect, Message, Result};

fn main() {
    if let Err(error) = connect("wss://data.alpaca.markets/stream", |out| {
        // 统一处理连接事件,和JS的事件监听逻辑对齐
        move |event| {
            match event {
                ws::Event::Open(_) => {
                    // 连接打开后再发消息
                    if out.send(r#"{"action": "authenticate","data": {"key_id": "<API_KEY>","secret_key": "<API_SECRET>"}}"#).is_err() {
                        println!("Websocket couldn't queue authenticate message.")
                    };
                    if out.send(r#"{"action": "listen","data": {"streams": ["AM.SPY"]}}"#).is_err() {
                        println!("Websocket couldn't queue listen message.")
                    };
                }
                ws::Event::Message(msg) => {
                    println!("message: '{}'. ", msg);
                }
                ws::Event::Error(err) => {
                    eprintln!("Error: {:?}", err);
                }
                _ => {}
            }
            Ok(())
        }
    }) {
        println!("Failed to create WebSocket due to: {:?}", error);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 21:36:01