Have a look at part 2 of the series, with focus on optimization.
Perhaps the most primitive use of Google App Engine Channel API is the use of chat between two people in real time. This concept can be extended to chatrooms - where many people chat simultaneously with each other, or gamerooms - where many people play some game simultaneously in real time amongst each other.
The docs don't say much about the quota details of Channel API, so here it is
Channel API Calls 46,310,400
Channels Created 8,640
Channel Data Sent 1,046.00 GBytes
Channel API Calls 91,995,495
Channels Created 95,040
Channel Data Sent 2,088.13 GBytes
The example application tic-tac-toe shows to a quite good level how to use Channel API for playing duo-player game. I find some scope for improvements in that app. Let's review them :
- Everytime a player starts a new game, a new client id (for channel) is created. The cap provided on Channels Creates is few, so this should be used judiciously
- The game room generates depends on the User. So, if the user who initiated the play reloads the page, the game is gone. This works for the case of tic-tac-toe but does not go for chatrooms or gamerooms
Apart from above issues, there are somethings that a serious gameroom/ chatroom needs and they are as follows:
- Automatic room creation. The room is automatically created as soon as number of players exceed the MAX_PLAYERS limit
- Every player has some assets (in a gameroom), and this keeps on changing with actions performed. So there needs to be state persistent information stored at the backend
- If the player reloads the page or opens a couple of new tabs, consistency of information should be maintained.
- Usually in a chat, when someone joins late, they want to be updated of the chats that took place when they were not there
Using above points as my guiding light, I tried to create an app which does the above in a net and beautiful manner. The app's source code is located at http://code.google.com/p/pranav/source/browse/chat-channel.
The concept of the gameroom/chatroom goes like this - When a player wants to play a game, he is taken to a room. The room could be a new room (if no room exists or all others are full), or an existing room.
There are two entity kinds - Game and PlayerGame. The Game Entity Kind contains information about the game room. This is where you can keep a track of all the events happening in a room like maybe chat between users, or collaborative drawing or the moves in a tic-tac-toe. The PlayerGame is a child entity of the Game entity, which contains the information about the game the user is playing. For those games which go in a sequential manner where player1 does something and then player2 does something, PlayerGame could have very well been inside the Game entity, but in a game where many players can do multiple actions and their actions affect their state in some way or the other datastore congestion might occur. To avoid all those, its made in a separate entity.
Then we need two wrapper Classes so that we can abstract the functioning. Our classes can very well be Player and Tournament.
The Player class contains all the wrapper functions that a player can possible do inside a chatroom/gameroom. Similarly, there shall be a Tournament class which will do all the activities that can be done in a tournament
FlowWhenever a user comes to the app, first of all it is checked if he was in an existing room or not. If found, then his activities are continued from that stage. If not found then the user is taken to a room. The room could be a new room, if all others are full, or no room is present. The user can perform activities in that room. Filling of rooms goes in First Come, First Serve order. So, when the next user wishes to join a room, the latest room created is checked for vacancy and the user is dropped there. The user is then free to perform actions and have fun. What is typically important here is that, initially a Channel is created between the client and the server, and then using that same channel all the future communication for rooms goes. One advantage of this is that we don't need to create a lot of channels for every user. For this it is very important that the algo which is used to create channel client id has only one variable as userid. (What will happen if we have two variables like userID and timestamp to create the channel client id?).
After the channel is created, the client send requests to join the room. This is taken care by the server and accordingly the user is dropped into a new room or an existing room
This is in a nutshell, a proof of concept about building huge chat-rooms/ game-rooms using Channel API of Google App Engine.
ResourcesRead more about optimizing this code in part 2 of the series.
- Source Code: http://code.google.com/p/pranav/source/browse/chat-channel
- Channel API: http://code.google.com/appengine/docs/python/channel
- Discuss: Google Groups Discussion
- Tic Tac Toe App: http://code.google.com/p/channel-tac-toe
There are many more things that needs to be taken care of to increase speed and performance, but that shall come in another blog post