Skip to content

Latest commit

 

History

History
 
 

backend

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Backend Readme

About this Document

Summary

This document provides details on how the backend of the software works, and provides "How to" for writing code to work with certain components. It is designed to supplement (and not repeat) the contents of the contributing document at the top-level of this project file hierarchy.

Target Audience

This document is targeted towards developers interested in contributing to the backend of this software project. See the External Documentation section for links to documents relevant to other areas of this project (e.g. frontend).

Document Scope

This document covers the following backend aspects of the project:
  • Server-sent Events.

External Documentation

If you are starting to contribute to this project for the first time, it is stongly recommended that you review the contributing document, which covers everything needed to start writing code for this project.

For developers interested in contributing to the project frontend, see the frontend README.

Server-Sent Events

What They are

They're essentially a means for a server to send data to a client without the client having to make any requests.

How it Works (from a brief implementation perspective)

  1. The client makes an event listener, just like any ol' event listener (click, mouseover, keypress, etc.).
  2. The server sends the event (which has the same name as what the client is listening for) to standard output along with data (which can be something like a bit of JSON).
  3. The client will receive this event and trigger the event callback.

Diagram

../documentation-images/sse_implementation.png

Events being Generated Server-side

This definition list shows which SSE events are being generated by the backend. Anything in angle brackets (<>) is a placeholder – <gameID> would be replaced by a game id. An ellipsis (…) represents potentially more entries in the same format.

playerJoin
[<username1>, <username2>, …]
gameStart
{"gameID": <gameID>, "propertyPositions": [<prop1>, <prop2>, …]}
playerMove
[[<playerId1>, <new position>, <old position>], [<pid2>, <new>, <old>], …]
playerTurn
{"name": <username>, "id": <userID>}
playerBalance
[[<userId1>, <newBalance>, <oldBalance>], [<uid2>, <new>, <old>], …]
propertyOwnerChanges
``[{"newOwner": null | {"id": <id>, "name": <username>},
"oldOwner": null | {"id": <id>, "name": <username>}, "property": {"name": <name>, "position": <position>}}, …]``

Writing Server-sent Event Generators (refers to events.py)

  1. Write a new function that performs some "check" to decide whether an event should be generated. e.g.

    def check_game_playing_status(output_stream, game):
        if game.state == "playing":
            generate_game_start_event(game.uid, output_stream)
    

    See events.py for more examples, all of which are commented.

  2. If the 'check' within the function you have written above passes, it should call another function (which you will write) to generate an event. e.g.

    def generate_game_start_event(game_id, output_stream):
        output_stream.write('event: gameStart\n')
        output_stream.write('data: %s\n' % (game_id))
        output_stream.write('\n\n')
    

    See the comments in generate_game_start_event() for some guidance on the sending of event types and the data payload.

  3. Finally, add the call to the function you wrote in 1. above, to start_sse_stream(). i.e.

    def start_sse_stream(output_stream=sys.stdout):
        ...
        while True:
            ...
            check_game_playing_status(output_stream, game)
            ...
            time.sleep(3)
        output_stream.flush()
    

    Make sure the call to your function is above the call to sleep()! There are a bunch of comments in start_sse_stream() which are worth a read, to supplement this README.