Can we flush with write and Frame

I have a simple code with a while loop which write to a websocket. As long as the loop is not complete, nothing shows on the client side (the message is not transmitted). Is there a way to flush to allow immediate writing?

My code:

extern crate log;

mod analysis;
use crate::analysis::{Init, Data};
use protobuf::{
    CodedInputStream, CodedOutputStream, Message, ProtobufResult, RepeatedField
};
use serde::{Deserialize, Serialize};
use std::time::{Duration, Instant};
use actix::prelude::*;
use actix_files as fs;
use actix_web::{
    middleware, web, App, Error, HttpRequest, HttpResponse, HttpServer
};
use actix_web_actors::ws;
use actix::Context;
use std::net::{TcpListener, TcpStream, IpAddr, Ipv4Addr, SocketAddr};
use std::io::{ self, BufReader, BufWriter, Read };
use std::fs::File;
use std::{thread, time};

/// do websocket handshake and start `MyWebSocket` actor
fn ws_index(r: HttpRequest, stream: web::Payload) -> Result<HttpResponse, Error> {
    println!("{:?}", r);
    let res = ws::start(Ws, &r, stream);
    println!("{:?}", res.as_ref().unwrap());
    res
}

struct Ws;

impl Actor for Ws {
    type Context = ws::WebsocketContext<Self>;
}

/// Handler for `ws::Message`
impl StreamHandler<ws::Message, ws::ProtocolError> for Ws {
    fn started(&mut self, ctx: &mut Self::Context) {
        println!("WebSocket session openned");
    }

    fn finished(&mut self, ctx: &mut Self::Context) {
        println!("WebSocket session closed");
    }
    
    fn handle(&mut self, msg: ws::Message, ctx: &mut Self::Context) {
        // process websocket messages
        match msg {
            ws::Message::Ping(msg) => {
            }
            ws::Message::Pong(_) => {
            }
            ws::Message::Text(text) => {
                println!("WS: {:?}", text);
                
                let ten_millis = time::Duration::from_millis(100);
                while(true) {
                    ctx.text("myString");
                    // ctx.flush();
                    thread::sleep(ten_millis);
                }
            }

            ws::Message::Binary(bin) => {
            }
            ws::Message::Close(_) => {
                ctx.stop();
            }
            ws::Message::Nop => (),
        }
    }
}

fn main() -> io::Result<()> {
    std::env::set_var("RUST_LOG", "actix_server=info,actix_web=info");
    env_logger::init();
    
    HttpServer::new(|| {
        App::new()
            // enable logger
            .wrap(middleware::Logger::default())
            // websocket route
            .service(web::resource("/ws/").route(web::get().to(ws_index)))
            // static files
            .service(fs::Files::new("/", "static/").index_file("index.html"))
    })
    
    // start http server on 127.0.0.1:3001
    .bind("127.0.0.1:3001")?
    .run()
}

Here is the library reference:

/// Send text frame
#[inline]
pub fn text<T: Into>(&mut self, text: T) {
self.write(Frame::message(text.into(), OpCode::Text, true, false));
}

while(true) {
    ctx.text("myString");
    // ctx.flush();
    thread::sleep(ten_millis);
}

Thanks!!

Did you ever get this working? I'm trying to do something similar but can't figure how to.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.