0

I am using actix-web to run a webserver and want to be able to mutate state through websocket messages.

My current way of using websockets is through implementing the handle method from actix::StreamHandler. However this limits my ability of passing data to it. How can I access the data (actix_web::web::Data) in my handle method?

The only way I can think of solving this issue is to somehow overwrite the function signature of handle, however that doesn't seem possible

LBlend
  • 31
  • 1
  • 4
  • It is site policy that posts on Stack Overflow should be self contained and only contain links to give further background info. Looking at the question like it is now (without looking at the links contents) it is lacking a lot fo details. – cafce25 Dec 11 '22 at 22:56
  • `StreamHandler` is a trait, meaning it must have an implementation. Have you created that implementation? Can you not store the required data in the type implementing that trait? – kmdreko Dec 11 '22 at 23:25

1 Answers1

1

Hers is some important code snippets, we have app_name and nonces in app_data:

// main.rs
let nonces = Arc::new(Mutex::new(nonces::Nonces::new()));

HttpServer::new(move || {
    App::new()
        .app_data(web::Data::new(app_data::AppData {
            app_name: String::from("Actix Web"),
            nonces: Arc::clone(&nonces),
        }))

    ...
// app_data.rs
pub struct AppData {
    pub app_name: String,
    pub nonces: Arc<Mutex<nonces::Nonces>>,
}
// ws.rs
struct Ws {
    app_data: web::Data<app_data::AppData>,
}

impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for Ws {
    fn handle(&mut self, msg: Result<ws::Message, ws::ProtocolError>, ctx: &mut Self::Context) {

        let app_name = &self.app_data.app_name;
        let mut nonces = self.app_data.nonces.lock().unwrap();

        println!(">>> {app_name}");
        println!(">>> {:?}", nonces.nonces);  // I have a nonces data in nonces

        ...
    }
}

async fn index(
    req: HttpRequest, 
    stream: web::Payload, 
    app_data: web::Data<app_data::AppData>,
) -> Result<HttpResponse, Error> {
    ws::start(Ws { app_data: app_data.clone() }, &req, stream)
}
kmdreko
  • 42,554
  • 6
  • 57
  • 106
Tim Lin
  • 11
  • 2