簡體   English   中英

如何制作 rust websocket 客戶端?

[英]How can I make a rust websocket client?

我嘗試過使用不同的庫和不同的實現,但我無法在 rust 中獲得一個正常工作的 WebSocket 客戶端/偵聽器。

我嘗試編寫一個處理程序:

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 函數。

先感謝您。

對於面臨同樣問題的任何人,我建議使用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.toml 中:

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

我面臨的問題是我使用的方法不是用於 TLS 流,而是用於 TCP 流。 使用 tungstenite,如果啟用 native-tls 功能,則 TCP 和 TLS 流都可以通過 connect 方法正確處理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM