Why AWS apigateway websockets backed by rust lambda's

Apigateway websockets

There are multiple ways to implement the websocket connection. I had made a game before using Signalr websockets and I'm still paying the monthly server fee to keep it all running. So I was interested in using the serverless variant of AWS, the apigateway websockets. It would mean I would have some limitations as the maximum connection duration of 2 hours and maximum frame size of 32 kb. These are not problematic for a game of rock paper scissors.

Rust C# why, o why

The second "problem" was that C# (the language I usually write in) has quite a slow cold start which is not ideal when you want the realtime feeling in the game (which could be solved with provisioned concurrency as well which might be pricy). Luckily, I was also trying to make more use of the rust language which has quite a good cold start and only becomes faster when it's warm. You could argue for other languages like js or python which also have lower cold starts but usually end up being slower than C# or rust when warm.

The flow of Rock paper scissors

The flow of the game was going to be quite simple. You connect to the websocket and you join the waiting list of people waiting to start a game. When someone else joins the waiting list and there are multiple players waiting, a game is started. Both the players are informed that the game has started and they get 5 seconds to send their play. After 5 seconds a trigger goes off to check what the players played and decides who the winner is.

For me there were two approaches to the timer, in a normal setup you would have some background task running that would check after 5 seconds, but in the serverless way you would probably not want to pay for a lambda waiting until it can take the next step. I was thinking I could use an SQS queue with a delayed delivery of 5 seconds, or use stepfunctions. For me the deciding factor was that there was more space in the free tier to use with the SQS; per month you can have 1.000.000 sqs requests vs 4000 state changes in stepfunctions. This decision will bite me a bit later (foreshadowing some doom scenario).

I'll take this moment to explain a bit about the apigateway websockets. AWS is responsible for keeping the websocket connection open and you're responsible for everything else (very short responsibility division doesn't cover the whole picture). In every websocket message there will be an action that you map to a lambda and you always have the action connect and disconnect. Here you receive the connection Id with which you can talk to the players later through this connection AWS keeps open for you. For all other actions you can create lambda's as well. So in my case, as you can see below, I have 4 actions Connect, Disconnect (they're in the same lambda), receive-play and join-game.

I came up with the following architecture to use for this game. I'll map the flow to the architecture in 4 steps.

  1. The connection to the Apigateway websockets is set up, which will trigger the connect lambda who in turn will store all the connection information. This information can later be used to send messages to the player.
  2. The player sends the intention to join a game. The join-game lambda checks in the DynamoDB if there are any players waiting to join the game. If there's a player ready to play a game they will both join the game and be informed of the starting game by making a call to Apigateway Websockets using their connection information. Once the game has started the game id is pushed to an SQS queue with a 5 second delivery delay.
  3. The rock paper scissors logic is trigged by the SQS queue after the 5 seconds are done. The logic will decide who's the winnner and send the players the outcome. If it was a draw the game id is pushed to the queue (see any problems in this thinking some more foreshadowing).
  4. All the players are disconnected from the game when a winner is decided. Which cleans up all the connection information and game relevant information.

This was the introduction to how rock paper scissors is setup. The next step is going to be translating this picture to CDK and deploying the infrastructure. the infrastructure

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.