axiom icon indicating copy to clipboard operation
axiom copied to clipboard

How to listen to a websocket in an actor?

Open sedrik opened this issue 4 years ago • 0 comments

Hi

I want to hide a websocket connection inside an actor to make it transparent to the rest of my system, I am however struggling with the proper setup using Axiom as I am unable to figure out how to enable listening to the websocket responses inside the actor. See the example below for how I am thinking that it should work (there are other unrelated compiler issues that I have not addressed so please ignore those for now).

use async_tungstenite::async_std::connect_async;
use axiom::prelude::*;

const WS_URL: &str = "wss://echo.websocket.org";

pub(crate) enum WsMessage {
    Command(String),
    Response(String),
}

pub struct Ws {
    socket: Option<()>, // TODO Fix this type
}

impl Ws {
    fn new() -> Self {
        Self {
            // TODO How/where can I listen to the ws_socket?
            socket: None,
        }
    }

    fn send(mut self, message: &str) -> ActorResult<Self> {
        if let Some(socket) = self.socket {
            socket.send(message);
        } else {
            panic!("Socket not initialized when sending");
        }
        Ok(Status::done(self))
    }

    pub async fn handle(self, context: Context, message: Message) -> ActorResult<Self> {
        if self.socket.is_none() {
            let (mut socket, _) = connect_async(WS_URL).await.unwrap();
            self.socket = Some(socket)
        }

        if let Some(msg) = message.content_as::<WsMessage>() {
            match &*msg {
                WsMessage::Command(command) => self.send(command),
                WsMessage::Response(response) => println!("response: {:?}", response),
            }
        } else {
            Ok(Status::done(self))
        }
    }
}

sedrik avatar Dec 17 '20 20:12 sedrik