- Sello Selepe - Nickname (Tebogo)
- We will be Implementing
Web Sockets
, We will create a game which will be played in real-time by 2-users perGame Loop
. This game will be calledBrandRace
. The general idea of the game is toguess
the logo of acar brand
quicker than youropponent
. More details of the game and its rules will be explained below. - Game Must Contain:
- A
PHP API
hosted off Wheatley that pulls from aMYSQL DB
. - Random Example,
config.php
Database Connection File.class ImagesDatabase{ private $Host = 'localhost'; private $DatabaseName = 'images_db'; private $Username = 'username'; private $Password = 'p@ssw0rd'; private $initConnection = null; // Creating an instance of the ImagesDatabase class public static function instance(){ static $instance = null; if ($instance === null){ $instance = new ImagesDatabase(); } return $instance; } // Method for Closing the database connection private function close($connection) { $connection->close(); } // The Constructor for the ImagesDatabase class private function __construct(){ if ($this->initConnection !== null){ if (mysqli_ping($this->initConnection)){ $this->initConnection->close(); } } // Initializing the Connection object $this->initConnection = new mysqli($this->Host, $this->Username, $this->Password); // Checking if Connection was successful if ($this->initConnection->connect_error){ die("Connection to the Database failed: " . $this->initConnection->connect_error); } else{ $this->initConnection->select_db($this->DatabaseName); } } // The Destructor for the ImagesDatabase class public function __destruct(){ // Check if the connection is still open and close it if (mysqli_ping($this->initConnection)){ $this->initConnection->close(); } } // Getting the Car image and brand_name public function getImage($random_number){ $UserQueryExecution = $this->initConnection->prepare("SELECT image,brand_name FROM race WHERE id = ?"); $UserQueryExecution->bind_param("i", $random_number); $UserQueryExecution->execute(); $result = $UserQueryExecution->get_result(); if ($result->num_rows > 0){ $row = $result->fetch_assoc(); // Do Something } else { return "No Image Found With ID: " + $random_number; } } }
- Random Example: Database Dumb For The
race
TableCREATE TABLE IF NOT EXISTS `race` ( `id` int(11) NOT NULL AUTO_INCREMENT, `brand_name` varchar(255), `image` varchar(255), PRIMARY KEY (`id`), UNIQUE KEY `brand_name` (`brand_name`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
- A
local NodeJS socket server
polling yourPHP API
from Wheatley. - Random Example. Local NodeJS socket server =>
Socket.io
socket.on("joinGame", ({ username, game_loop }) => { const user = userJoin(socket.id, username, game_loop); socket.join(user.game_loop); // Welcome current user socket.emit("message", formatMessage(botName, "Welcome to BrandRace!")); // Broadcast when a user connects socket.broadcast .to(user.game_loop) .emit( "message", formatMessage(botName, `${user.username} has joined the game`) ); // Send users and game_loop info io.to(user.game_loop).emit("Competitors", { game_loop: user.game_loop, users: getCompetitors(user.game_loop), }); });
- A
Web client
that connects to yourNodeJS socket
server and will act as theFront End
. - Random Example.
index.html
<!DOCTYPE html> <html lang="en"> <head> <title>Brand Race</title> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" type="text/css" href="styles.css" crossorigin="anonymous"/> </head> <body> <div class="join-container"> <header class="join-header"> <h1><i class="fas fa-smile"></i>Brand Race</h1> </header> <main class="join-main"> <form action="game_loop.html"> <div class="form-control"> <label for="username">Username</label> <input type="text" name="username" id="username" placeholder="Enter username..." required/> </div> <div class="form-control"> <label for="game_loop">Game Loop</label> <select name="game_loop" id="game_loop"> <option value="game_loop">Game Loop 1</option> </select> </div> <button type="submit" class="btn">Game Loop 1</button> </form> </main> </div> </body> </html>
- A
-
- NodeJS
- JS
- HTML & CSS (Bootstrap)
- PHP
-
-
MySQL
DB- Ability to
store
images in theDB
- Ability to
retrieve
images from anendpoint
- The
image(s)
should be random every API Call - ReadMe explanation,
1 vs 5
images at a time - ReadMe explanation,
Base64
vsLink
-
Task Pending
.Port
can bechosen
atrun-time
Reserved Ports
cannot be chosen- Server can accept
multiple
clientssimultaneously
'LIST'
command is implemented and fully functioning'KILL'
command is implemented and fully functioning'QUIT'
command is implemented and fully functioning'GAMES'
command is implemented and fully functioning- If
connection
isclosed
on the client theserver closes
thesocket
- Server keeps
track
of usernames - Server can
detect
When a game shouldstart
and start the game on theuser
side - Server can
send
throughImages
to the client usingsockets
and theAPI
- Server can
generate
aunique
GameID
- Server implements the
flow
of theGameLoop
correctly
-
- The client can
connect
to a server through asocket
- The client allows the user to
choose
ausername
- The client allows user to
enter
ORgenerate
GameIDfrom
the server - The client starts the Game Loop on the user side on
cue
from the server - Error
Messages
(Username taken, Socket disconnected, Opponent Gets a point, etc.) - The ability to implement the Game loop correctly
- The client can
-
-
The aim of
BrandRace
, is to guess aCar Brand Logo
faster then your opponent. There will be atotal
of5 rounds
, in each round the players will see anew
Logo onscreen
and need toenter
the correct name to get the point, whoever does this the quickestwins
the round. Thewinner
is the player that has won themost
rounds. However you are also racing against theclock
, each player will havelimited time
each round and if time runs out before any player guesses the correct logo thenno one
gets the point. -
To make the game a bit easier to follow please consult the
diagram below
. The Area highlighted inRed
will be referred to as theGame Loop
and is referenced throughout the specification. Before the game begins a userchooses
ausername
and has the option to eithergenerate
aGameID
orenter
in aGameID
. When avalid
GameID
is entered itautomatically
starts theGame Loop
After a5 seconds
countdown on both screens. -
This is a
2 player
game(1 vs 1)
, if someone else enters in a GameID that isalready in progress
(game started) theyshould not
be allowed to join in the game and an appropriateerror message
should be shown.
-
-
-
-
We will create a PHP API that is hosted off Wheatley as well as a
MYSQL DB
along with it. ThisAPI
should have one endpoint,GetRandomBrands
. In this endpoint we will choose between returning 5random
Car brand logos with theirnames
OR 1random
Car brand logo with itsname
that should be retrieved from theMYSQL
Database. There are 2 options when dealing with images. Since images themselves cannot be transferred through an API we will store the images inBase64
format in the database and return theBase64 String
. (Consult the resources about working with Base64 at the top of the doc) OR Alternatively we can send through alink
to the image that is hosted somewhere on theinternet
which we will then display. We will populate the DBmanually
withPHPMyAdmin
for this assignment. Below is a summary of what is mentioned above: -
We have 2 options of how we can set up the API. There is no incorrect answer here, We shall motivate our choices
(5 At once)
- This option will return an array of 5 different Car Brand Logos + Names in a single API Call(1 At a time)
- This option will only return 1 Car Brand Logo + Name at a time
-
We will write a short explanation of our choice and why we believe its the better option. We have 2 Options of how we can transfer images. There is no incorrect answer/choice here, but we need to back up our choice
-
- Encryption method in PHP:
base64_encode()
- Encryption method in PHP:
base64_decode()
- Encryption method in PHP:
-
-
We will write a
short
explanation of our choice and why we believe its thebetter
option.
-
-
- For this task we will create a
Multi-User
socket server(on localhost)
. The server will coded inNodeJS
locally and not off wheatley. We will uselibraries
for this. Note: Wheatley is a web server that follows theLAMP
stack and installing other applications on it brings security issues. We will therefore uselocalhost
for this since theNodeJS server
needs to run on an openport
and it would be difficult to allow the server to be run on Wheatley as the chances of multiple people using the same port would be high. -
- Be able to
specify
a port that theserver
willlisten
on atrun-time
(create the socket), using input arguments or prompts. It is good practice toblock
the user from usingreserved
ports (Ports that have been reserved for other task). However there is still a chance we can choose a port in use, but we will just try a different port instead. The ports we will use ports from1024
to49151
, make sure the user can onlychoose a port in this range
. If you are curious about why this is the case, you can read up about it at https://www.techtarget.com/searchnetworking/definition/port-number. -
Definition
: A port number is a way to identify a specific process to which an internet or other network message is to be forwarded when it arrives at a server. All network-connected devices come equipped with standardized ports that have an assigned number. These numbers are reserved for certain protocols and their associated function. Hypertext Transfer Protocol (HTTP
) messages, for example, always go to port 80 -- one of the most commonly used ports.
- Be able to
Block
the user from attempting to open a Reserved Port (Explained above).- Accept
multiple
client connections and interact with the clientsconcurrently
through sockets. - The server must utilize functionality of the
PHP API
we developed inTask 1
. That means our server shouldcontact
our PHP API to get the car brands for the game based on the options we chose. - The server should have a
KILL
command toclose
a connection based on theirusername
. This also means that we need to keep track of whichsocket ID
corresponds to which Username since we need the SocketID toclose
asocket connection
. - The server needs to
account
forlost
sockets (when a socket was created and the client[HTML web page]
hasclosed/disconnected
). These lost sockets should be closed in order to allow for new connections. If that user wasin a game
then thegame should be stopped
and the otheruser
notified (This check can be done in the game loop
). - The server should have a
LIST
command tolist all
the connections it currently has, be sure to list theusernames
and their respectiveSocketIDs
. - The server should have a
QUIT
command thatsends
abroadcast
to all connections notifying that the server will now gooff-line
, thereafter closing all connections. - The server should have a
GAMES
command thatshows all games
insession
orcreated
, TheGameID
and theplayers usernames
. - The server should be able to
keep track
ofusernames
, i.e a when a user requests a username the serverdetermines
if itsin use
, prompting for adifferent username
. - The server should be able to
generate
aUnique GameID
. This should be a random10
CharacterAlphaNumeric
String. - The server should be able to start the game loop automatically if a user enters in another users
GameID
(remember the5 second countdown
). - The
Game loop
, Once the game loop has started take note of the following from theserver side
:- The server should
notify
the user when the game isabout to start
- The server should
keep track
how manyrounds
each user haswon
Detect
if oneopponent disconnects
andend
the loop and notify the other- The server should be able to implement what is shown in the
Flowchart
underGame Details
- The server should
- Since Wheatley is password protected, Include login details in the URL as follows:
username:password@wheatley.cs.up.ac.za/uXXXXXXXX/path/to/api
-
To
test
the functionality of the server will use https://www.piesocket.com/websocket-tester as the clientbefore
proceeding to Task 3.
- For this task we will create a
-
- For this task we will
develop
aweb page/web site
that willinteract
with ourserver
(that runs on our local machine[localhost]
) we wrote for Task 2. The web client must be implemented inHTML
,CSS
andJS
usingWeb Sockets
. The client should also be onlocalhost
. Note: We will use some client sidelibrary
of our choice(e.g. WebSockets, Socket.io, etc.)
. To make the changes we can/should make use ofDOM Manipulation
withjavascript
, that way we do not need toredirect
to a new page every time which might disconnect the socket. -
- The user should be able to
enter
in their username. If that username isnot available
then anerror
should be shown, and beallowed
to enter in anew username
. - After the user has
received
a username they have 2 optionsEnter
in aGameID
. If the GameIDexists
and the game in not improgress
shouldtrigger
the game loop.Generate
aGameID
(From the server) start the game loop when another user enters in theGameID
.
-
- Once the server starts the game loop the
screen
shouldupdate
to show the logo with aelapsed timer
, and the ability for a user to enter in thebrand name
. Here we are free to chose how the user inputs the name. - The user should be able to guess the
logo
and benotified
if they get itright
orwrong
(remember this needs to happen inreal-time
). When a user gets itwrong
, they should be allowed totry again
, provided their opponent has not got it correct, andvice versa
. - The user should be
notified
if their opponentgets it right
and what thecorrect answer
was before moving onto the next logo. Toaid
user experience use acountdown
timerbefore
moving to the next logo.
- Once the server starts the game loop the
- At the
end
of the game both users should benotified
of thewinner
unless it was adraw
.
- The user should be able to
- For this task we will
-
-
- A text editor is required to create, write and edit code.
- There are many free and paid text editors available online such as Visual Studio Code, Sublime Text, Notepad++, and Atom.
- VS Code Instalation Guide: https://www.youtube.com/watch?v=4zVObKFZ6fA&ab_channel=TheCodeholic
-
- A web server is required to serve web pages to users.
- You can use an existing web server like Apache or Nginx, or you can use a package like XAMPP or WAMP which comes with an integrated web server.
- Once
Xampp
is available:- Copy the souce code to the httdoc directory
- Run
Apache
andMySQL
server - url:
"http://localhost/path/to/code/login.php"
-
- Hypertext Markup Language is used to create the structure and content of web pages.
- You need a text editor to create HTML files with an ".html" extension.
-
- Cascading Style Sheets are used to style the HTML content.
- You need a text editor to create CSS files with a ".css" extension.
-
- JavaScript is used to add interactivity and functionality to web pages.
- You need a text editor to create JavaScript files with a ".js" extension.
-
- PHP is a server-side scripting language used for dynamic web content.
- You need a web server that supports PHP to run PHP scripts.
-
- jQuery is a JavaScript library that simplifies HTML document manipulation, event handling, and animation.
- You need to include jQuery in your HTML file by linking to it in your code.
- The Same AJAX Example Using jQuery Just For Control
<!DOCTYPE html> <html> <head> <title>AJAX Example For Control</title> <!-- Including jQuery Library in out file --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script> $(document).ready(function() { $("#exampleButton").click(function() { $.get("URL", function(data) { // DOM Manipulation $("#example_id").html(data); }); }); }); </script> </head> <body> <h1>AJAX Example For Control</h1> <button type="button" id="exampleButton">Load Data</button> <p id="example_id"></p> </body> </html>
-
- A web browser is necessary to render and display web pages.
- Popular web browsers include:
- Google Chrome
- Mozilla Firefox
- Safari
- Microsoft Edge
- Brave
- Opera Mini
- Not Recommended: Tor (Onion Routing)