如何创建rust WebSocket客户端?

k2fxgqgv  于 2023-04-21  发布在  其他
关注(0)|答案(2)|浏览(269)

我尝试过使用不同的库和不同的实现,但我无法在rust中获得一个工作的WebSocket客户端/侦听器。
我试着写了一个handler:

extern crate ws;

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

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 main() {
    if let Err(error) = listen("wss://data.alpaca.markets/stream", |out| {
        Client { out: out }
    }) {
        println!("Failed to create WebSocket due to: {:?}", error);
    }
}

我也试过这个:

extern crate ws;

use ws::{connect, CloseCode};

fn main() {
    if let Err(error) = connect("wss://data.alpaca.markets/stream", |out| {
        if out.send(r#"{"action": "authenticate","data": {"key_id": "<API_KEY>","secret_key": "<API_SECRET>"}}"#).is_err() {
            println!("Websocket couldn't queue an initial message.")
        } else {
            println!("Client sent message 'Hello WebSocket'. ")
        };

        if out.send(r#"{"action": "listen","data": {"streams": ["AM.SPY"]}}"#).is_err() {
            println!("Websocket couldn't queue an initial message.")
        } else {
            println!("Client sent message 'Hello WebSocket'. ")
        };

        move |msg| {
            println!("message: '{}'. ", msg);

            Ok(())
        }
    }) {
        println!("Failed to create WebSocket due to: {:?}", error);
    }
}

为了确保我尝试连接的连接不是问题所在,我用JS编写了相同的代码。

const ws = require("ws");

const stream = new ws("wss://data.alpaca.markets/stream");

stream.on("open", () => {
    stream.send('{"action": "authenticate","data": {"key_id": "<API_KEY>","secret_key": "API_SECRET"}}');
    stream.send('{"action": "listen","data": {"streams": ["AM.SPY"]}}');
});

stream.on("message", (bar) => {
    process.stdout.write(`${bar}\n`);
});

在rust代码的两个示例中,代码编译并运行,但on_open函数和lambda函数从未被调用。
先谢谢你。

k4aesqcs

k4aesqcs1#

对于任何面临同样问题的人,我建议使用tungstenite和异步websockets tokio-tungstenite
这是我最终使用的代码:

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

let (mut socket, response) = connect(
    Url::parse("wss://data.alpaca.markets/stream").unwrap()
).expect("Can't connect");

socket.write_message(Message::Text(r#"{
    "action": "authenticate",
    "data": {
        "key_id": "API-KEY",
        "secret_key": "SECRET-KEY"
    }
}"#.into()));

socket.write_message(Message::Text(r#"{
    "action": "listen",
    "data": {
        "streams": ["AM.SPY"]
    }
}"#.into()));

loop {
    let msg = socket.read_message().expect("Error reading message");
    println!("Received: {}", msg);
}

这是在Cargo.

[dependencies]
tungstenite = {version = "0.16.0", features = ["native-tls"]}
url = "2.2.2"

我所面临的问题是,我使用的方法不是用于TLS流,而是TCP流。使用tungstenite,如果您启用native-tls功能,TCP和TLS流都可以通过connect方法正确处理。

cuxqih21

cuxqih212#

时雄钨矿石怎么样?

use tokio_tungstenite::connect_async;
use tokio_tungstenite::tungstenite::Message;

let strurl = format!("{}/ws?listenKey={}", WSS_URL, &listenkey);
let url = Url::parse(&strurl)?;
let (mut socket, _) = connect_async(url).await?;

let msg_tobe_send = Message::text("{\"method\":\"ping\"}").into();

loop {
  socket.send(msg_tobe_send).await?;
  let message = socket.next().await.ok_or("No response from server")??;
  println!("Received message: = {:?}", message);
}

在发送行,得到以下错误:

traits中的struct WebSocketStream在当前作用域中找不到名为send的方法只有trait在作用域中才能使用

相关问题