Repository: tokio-rs/axum
File: examples/websockets/src/main.rs (Rust)

Code before:
        }
    }

    // we can also send messages to client by simply sleeping,
    // since each client gets individual statemachine. Thus, waiting for this
    // client to finish getting his greetings does not prevent other clients form
    // connecting to server.
    for i in 1..5 {
        if socket
            .send(Message::Text(String::from(format!("Hi {} times!", i))))
            .await
            .is_err()
        {
            println!("client abruptly disconnected");
            return;
        }
        tokio::time::sleep(std::time::Duration::from_millis(100)).await;
    }

    // By splitting socket we can send and receive at the same time. In this example we will send
    // unsolicited messages to client based on some sort of server's internal event (i.e .timer).
    let (mut sender, mut receiver) = socket.split();

    // Spawn a task that will push 100 messages to the client (does not matter what client does)
    let mut send_task = tokio::spawn(async move {
        let mut i = 20;
        while i > 0 {
            // In any websocket error, break loop.
            if sender
                .send(Message::Text(format!("{} messages left...", i)))
                .await
                .is_err()
            {
                break;
            }

            tokio::time::sleep(std::time::Duration::from_millis(300)).await;
            i -= 1;
        }
        if i == 0 {
            println!("Sending close to {}...", who);
            if let Err(e) = sender
                .send(Message::Close(Some(CloseFrame {
                    code: 1000,
                    reason: Cow::from("Goodbye"),
                })))
                .await
            {
                println!("Could not send Close due to {}, probably it is ok?", e);
            }
        }

Review comment (suggestion):
I think this should be `for n in 0..20 { ... }` to do something 20 times.

Code after:
            if process_message(msg, who).is_break() {
                return;
            }
        } else {
            println!("client {} abruptly disconnected", who);
            return;
        }
    }

    // Since each client gets individual statemachine, we can pause handling
    // when necessary to wait for some external event (in this case illustrated by sleeping).
    // Waiting for this client to finish getting his greetings does not prevent other clients form
    // connecting to server and receiving their greetings.
    for i in 1..5 {
        if socket
            .send(Message::Text(String::from(format!("Hi {} times!", i))))
            .await
            .is_err()
        {
            println!("client {} abruptly disconnected", who);
            return;
        }
        tokio::time::sleep(std::time::Duration::from_millis(100)).await;
    }

    // By splitting socket we can send and receive at the same time. In this example we will send
    // unsolicited messages to client based on some sort of server's internal event (i.e .timer).
    let (mut sender, mut receiver) = socket.split();

    // Spawn a task that will push several messages to the client (does not matter what client does)
    let mut send_task = tokio::spawn(async move {
        let n_msg = 20;
        for i in 0..n_msg {
            // In case of any websocket error, we exit.
            if sender
                .send(Message::Text(format!("Server message {} ...", i)))
                .await
                .is_err()
            {
                return i;
            }

            tokio::time::sleep(std::time::Duration::from_millis(300)).await;
        }

        println!("Sending close to {}...", who);
        if let Err(e) = sender
            .send(Message::Close(Some(CloseFrame {
                code: axum::extract::ws::close_code::NORMAL,
                reason: Cow::from("Goodbye"),
            })))