Skip to content

passing information between the client & server

Tylar edited this page Jul 17, 2014 · 7 revisions

If you're developing on asteroid.ventures you may have noticed that a lot of the game logic is stored on the server. This is for two reasons: 1) trusting the client too much makes cheating too easy, 2) Tylar likes coding python much more than javascript. =)

Now, because a lot of game information is on the server, there needs to be a lot of communication between the server & the client application. It is very likely that the new game feature you are working on is going to need to tell the game server something, so this page is here to help. There are a few ways the game and client can communicate, here we cover: 1) how to use websockets to pass custom messages, 2) how to use websockets to add html to the "content" section, 3) how to set up and use a new POST route, and 4) how to set up a new GET route.

It may also be helpful to check out an intro to websockets or the bottle.py tutorial.

Using Websocket Messages

When you log into asteroid.ventures and a game is started a websocket connection between the client and server is opened, and it stays open until the game ends (this is done by tpl/js/websocketsetup). This allows for lightning fast passing of information between client and server. The information sent over the socket is just a string of characters, but we have an established message syntax to help things work smoothly. This message syntax is defined in both js (on the client) and in python (on the server), and the two must agree for it to work correctly.

The Websocket Syntax

Our messengers/parsers assume that websocket messages from client->server are strings in the following form: { "uID":user_id, "gID":game_id, "cmd":command, "dat":data } and for server->client: { "cmd":command, "dat":data }

You may notice that this string defines a dict in python if "eval"d. "user_id" and "game_id" allow us to identify who is sending the request and who should care easily. "command" is an arbitrary string that specifies what exactly is being requested. The "command" string is what the message parsers use to determine what action needs to be taken. Lastly, "data" is any arbitrary string which contains any data that may be needed to complete the given command.

Communication through websockets is two-way, so let's break this down based on which direction we want to go.

Client -> server

In order to send a websocket from the game client we can use the already read-to-go websocket connection and the message creation function in /js/createMessage.js to handle user_id and game_id for us. Thus the command just becomes: ws.send( message( 'myCommand', 'myData' )). You can even leave off the data parameter and just send a command like this example. Just add this js to a button's onClick listener, use it from your javascript, or even try it from the js console.

Now that we're sending our message, we need to jump into server-side code and define how the server responds to our new "myCommand" message. Websocket parsing in the server is handled by /py/webSocketParser.py, so you can jump over there to see how existing commands work. In order to add "myCommand" just add an additional elif conditional to the parse() function.

Now you can issue commands from javascript, and perform any python you want server-side!

server->client

This works almost identically to the above, but with python and js flip-flopped. So to send messages, we use the python message creator in py/webSocketMessenger.py, and the user's websocket instance like so: user.websocket.send( createMessage( 'myCommand', 'cmdData' ))

And to handle the message on the client we add an additional else if to /js/wsMessageParser.js's parseMessage function.

Using Websockets to Append HTML to the "Content" Section

Now I'm going to talk about one special server->client websocket command which is implemented because I think it is cool (and maybe useful). The game pages all share a common frame which has a "content" section that changes as links are clicked. This is so we don't have to reload the whole page just to navigate the game. Content sections can be overloaded using jquery's $.load() function. This is explained in more detail in the page layout breakdown

In addition to replacing all the content, the "addToContent" command allows arbitrary html chunks to be appended to the content section. This is how we are able to get textBoxes to pop up when asteroid track requests are sent from the asteroid search views. Remember, the syntax is like this: user.websocket.send( createMessage( 'addToContent', '<div><h1>Wot wot wot?</h1></div>' )). It might help you a lot to use a content tile template like those in /tpl/content/tiles/, so that would be like: user.websocket.send( createMessage( 'addToContent', template('tpl/content/tiles/textonly', text='testText', title='myTitle', color='purple' ))). Enjoy!

Setting Up & Using a POST Route

TODO

Setting Up & Using a GET Route

TODO