#tokio::sync::mpsc::Receiver not receiving from cloned sender that got passed through a channel?

17 messages · Page 1 of 1 (latest)

spare osprey
#

i am programming a multiplayer game. for each connection i wait for a spawn command from the client and then send the client information (id and the server_message_tx) to the game calculation tokio task. my problem is that the server_message_tx (sender) doesnt seem to work anymore after being passed through the channel, but its only a clone of its original. the original server_message_tx does still work. by working i mean that the receiver doesnt get the messages and the sender after a few messages gets send error because channel is full.

#

i marked some test sections with // TEMP to see if the channel was working at that point

#

the problem occurs in this part. the server_message_tx_clone successfully arives but sending messages from the other side with it doesnt work

#

other side of the channel looks like this:

fringe dragon
#

That try_recv is suspicious

#

What happens when it returns None?

spare osprey
#

it continues with the game calculation, which happens because the broadcast function at the end gets executed permamently

    loop {
        // get new client channels
        while let Ok(sender) = {sender_receiver.try_recv()} {
            println!("getting sender");
            // TEMP doesnt work
            sender.sender.try_send(Arc::new(ServerMessage::dummy()));

            server_message_senders.push(sender);
        }

        // delta time calculation here
        let now = Instant::now();
        let delta_time = now.duration_since(last_time);
        last_time = now;
        let delta_seconds = delta_time.as_secs_f64();

        // receive client input
        while let Ok(client_message) = client_message_receiver.try_recv() {
            let result = client_message.request_data.execute(&mut game_objects, delta_seconds).log();
        }

        // game logic calculation
        let update_result = update_game(&mut game_objects, delta_seconds).log();

        // creating message for sending
        let object_data = ObjectData {
            game_objects
        };
        let server_message = ServerMessage {
            request_info: RequestInfo::new(get_time() as f64),
            request_data: object_data,
        };

        // sending message
        broadcast(&mut server_message_senders, &server_message, delta_seconds);

        // retrieving ownership of data
        game_objects = server_message.request_data.game_objects;
    }
fringe dragon
#

I don't see any .await in that loop. Read the article I linked to understand why that's important.

spare osprey
#

i understand what you are saying, but the thread is not blocking here, or at least that wouldnt be a permanent block

#

i know that because the broadcast function gives me the feedback that the channel appears to be full after a while

pub fn broadcast(senders: &mut Vec<ServerMessageSenderChannel>, message: &ServerMessage, delta_seconds: f64) {
    let shared_message = Arc::new(message.clone()); // Wrap the message in an Arc
    let mut to_be_removed = Vec::<usize>::new();
    // send messages to all
    for (i, sender_channel) in senders.iter_mut().enumerate() {
        sender_channel.tick_counter += delta_seconds;
        if sender_channel.tick_counter >= sender_channel.update_threshold {
            // send message to client
            println!("trying to send to client");
            sender_channel.tick_counter = 0.;
            let message_clone = Arc::clone(&shared_message);
            if let Err(e) = sender_channel.sender.try_send(message_clone) {
                match e {
                    error::TrySendError::Full(_) => {
                        eprintln!("Failed to send message: {}", e);
                    },
                    error::TrySendError::Closed(_) => {
                        eprintln!("Failed to send message: {}", e);
                        // remove connection
                        to_be_removed.push(i);
                    },
                };
            }
        }
        else {
            // println!("tick not there yet {} - {}", sender_channel.tick_counter, sender_channel.update_threshold);
        }
    }
    // remove senders that are closed
    for i in to_be_removed.iter().rev() {
        senders.remove(*i);
    }
}
fringe dragon
#

Can you try using tokio-console and sharing what it says?

spare osprey
#

let me look up what that is, i am pretty new to tokio

#

sorry can i continue later? i got a groupwork todo now

fringe dragon
#

Of course