Setting up the logic

So what do we need to do in the connect and disconnect? The AWS api gateway doesn't store connection information. So to be able to send messages to a connected client we need to keep track of who is connected.

This we'll do by saving the connection id's in a dynamodb table and store other relevant information with that. We'll use the one dynamodb table approach to keep it interesting. I would not personally recommend it but AWS has some nice videos about it. Short summary of the videos: if everything is in a dynamodb table, which can grow unlimited without performance degradation, you can scale your database in a cheaper way. You just really need to think about your access patterns.

Ok no more distractions let's go look at the connection lambda. In the last chapter you could see the entrypoint for the lambda that directed it to a function. Let's dive into that part.

#![allow(unused)]
fn main() {
use rusoto_core::Region;
use rusoto_dynamodb::DynamoDbClient;

lazy_static! {
    /// This is a client for connecting to dynamodb which will be loaded once
    static ref CLIENT:DynamoDbClient = DynamoDbClient::new(Region::EuCentral1);
}

async fn on_connect(event: Event) {
    store_connection(event.request_context.connection_id, None).await;
}


async fn store_connection(connection_id: String, game_id: Option<String>) {
    let player = Player::new(connection_id, game_id);
    put_player(player).await
}

pub async fn put_player(player: Player) {
    let mut put_item = serde_dynamodb::to_hashmap(&player).unwrap();
    put_item.insert("Changed".to_string(), AttributeValue { s: Some(Utc::now().to_string()), ..Default::default() } );

    let result = CLIENT
        .put_item(PutItemInput {
            item: put_item,
            table_name: TABLE_NAME.to_string(),
            ..Default::default()
        })
        .await;
    match result {
        Ok(_) => println!("succesfiully saved connection"),
        Err(e) => println!("error in writing to dynamodb {}", e),
    }
}
}

Ok, I took out the parts of code from different files and put them together to create a short overview of what happens on connect. I hope the code speaks for itself. It just stores the connection id we get from AWS and saves it with an empty game id. serde_dynamodb helps with turning the rust struct into a dynamodb accepted object. However, not all types are supported, so check out the list here

The dynamodb client is from the rusoto package which is an unofficial library that makes it easier to make calls to AWS. There's also an official rust sdk from AWS but when I'm writing this it's still in developer preview and not recommended for production use.

In the next chapter we see what happens on disconnect. So far not a lot of crazy stuff, might be because we glossed over some parts, which are hiding some matchmaking logic but we'll get there someday.

Thanks for reading

I enjoyed trying to make everything and I hope you'll enjoy reading it. If you are excited to have a chat or think I could improve feel free to write me on LinkedIn. I also have portfolio website where I put most of what I make and host trial projects portfolio.rohanengosia.com.