Message Broker
 
API Reference: Message Broker

1.           Structure

 

Follows the order and type of messages to be exchanged.

The API consists of two main libraries:

web.js:  Responsible for monitoring the messages and for calling the methods of the games.

•webVar.js: API global variables.

All API messages will have a String format and use a ";" separator for the different parts of the message.

 

1.1.    Libreries

1.1.1.  webVar.js

This library includes the API code with variables like the server IP and port, among other things. These messages should not be changed as they are used to communicate with the server.

This class includes two parameters that can be changed depending on the network.

var MAIN_SERVER_ADDRESS = '213.37.1.75';

o   Server Address.

·         var APP_ID = '47d97160f684716248223337348f11a6';

o   Application Id, this is supplied when an App is registered in the Web.

 

 

1.1.2.  Web.js

 

This library includes the code handling the API, messages, socket etc.….

1.1.3.  JQuery

JavaScript library

1.2.    Messages

1.2.1.  Type of  m essages

 

Messages for the communication with the Server:

·         INICIO = 0                                          received  at receivingData

·         BEGIN_SESSION = 1                      received  at receivingData

·         ACTION = 2                                       received  at receivingGameData

·         END_SESSION = 3                           received  at receivingGameData

·         NEW_SALA = 4                                received  at receivingData

Game Error Message:

·         OK = 200            

·         ERROR_NO_APP = 501

·         ERROR_NO_SESIONES = 502

·         ERROR_NO_SALAS = 503

·         ERROR_NO_SALA = 504

·         ERROR_SALA_REP = 505

API Error Messages:

·         MEN_ULTIMO = "ultimoJugador"   (Last player)

·         MEN_CONECTADO = "conectado"   (connected)

These messages are received through the API methods:

·         function receivingData(socketId)

·         function receivingGameData (socketId)

1.2.2.  Message INICIO (start)

 

This is the start message that launches the API to communicate with the Server. It answers with the playing Rooms available; this info is displayed in a table.

The server response is given in the form of JSON, the API will try this json and display information in HTML format.

This message will be sent continuously so that the information is updated, when performing an action, either entering a new room or hall, the startup message is no longer sent, when performing an action game "end room" the message is automatically sent again, this message is sent via UDP socket using the agreed start port.

The interval at which this message is sent can be controlled with the variable "limitLatencyToInicio", this variable is on the file webVar.js.

The following Table shows the room name, the port used for that room, the status and support sessions available, the creation date and the option to enter it if it is open.

 

 

Server message:

·         function callInicioSocket (pNameSala)

·         INICIO:  type of message

·         APP_ID; id application (Game).

This generates a Server message , It creates a json with the Rooms and it will return a message to the API with the following information.

 

·         typeMen: Type of mensaje.

·         Error Message: OK if ok, ERROR_NO_SALAS if no rooms are available, ERROR_NO_APP, error if there is no application in the bbdd. ERROR_SALA_REP, repeated room for this application.

·         json: Room  information in  json format.                            

1.2.3.  Message NEW_SALA (New Room)

 

This message is started when a new room option is available and is used to start up a new Room. The Room Name and the Number of Players (four Players maximum and two by default) has to be provided.

Server Message:

·         function callNewSalaSocket(pNameSala)

·         NEW_SALA: Type of Message.

·         APP_ID; Application Id (Game).

·         MAX_PLAYER: Maximum number of players.

·         pNameSala:  Room Name.

 

With this info the server message is created .A Room will be created with the indicated Number. An id and the maximum number of players are assigned and a Message will be returned to the API with the following info:

 

·         typeMen: Type of Message.

·         Error Message: OK if ok, ERROR_SALA_REP if the Room Name is duplicated, ERROR_NO_APP, if no application exists in the bbdd.

·         Session Id:     Session Id, user connected.

·         Room Port:  Port used by the new socket to start the Game communications.

·         Number of users connected to the Room.

·         Room Name.

·         Maximum number of players.

 

Up to now everything was controlled by the API, the main socket is stopped and a socket for the  Game with the port message is created. When the API receives the Server Message answering the message NEW SALA (new Room) it will start the Game which is called though a method implemented by the Game.

                              

·         preInit(ROOM_NAME, USER_NUMBER, MAX_PLAYER);

o   ROOM:  Room to be connected.

o   USER_NUMBER:  User id for the Game.

o   MAX_PLAYER: Maximum number of players for this Room

 

When a new socket is launched the API sends a message to the Server with a new action, this is performed with the message ACTION sent to the new socket. This arrives to the server and the Server answers to all Room players.

 

This message contains information written from the Game point of view depending on the connected users or if it is the last to be connected. This is controlled by the Game that should confirm when the user has been correctly connected (MEN_CONECTADO) and when it is the last (MEN_ULTIMO). The Game may establish optionally a MASTER user for the Game. This will be explained later in more detail.

 

·         priorWriteAction(MEN_TYPE_BEGIN + : + userId + : + MEN_ULTIMO);

·         priorWriteAction(MEN_TYPE_BEGIN + : + userId + : + MEN_CONECTADO)

 

 

The interval between messages can be established in the same way as with the start message with the variable “limitLatencyToInicio” available in the webVar.js file

 

1.2.4.  BEGIN SESSION Message

 

This message is sent when the option enter Room is granted.

 

Message to the server:

·         function callBeginSocket(idSala)  

·         BEGIN_SESSION: Type of Message.

·         APP_ID; Application Id   (Game).

·         MAX_PLAYER:  Maximum number of players for this Room.

·         idSala: Room id from the Room  requested to join.

·         USER_ID:  Assigned user Id

 

This generates a message to the server. A user with the calling IP and port is generated. This user is assigned an Id and it will enter the Room. The API will receive a message with the following information:

·         typeMen: Type of Message.

·         Error Message : OK if ok, ERROR_NO_SALA if the Room is not available , ERROR_NO_APP, if the Application is not available on the bbdd.

·         Room Id:  Room Id where it has been connected.

·         Session Id:   Session Id for the connected user.

·         Room Port:  Port used by the new socket to start communications with the Game.

·         Number of users connected to this Room.

·         Name of the Room.

·         Maximum number of players for this Room.

 

Like for the New Room Message the main socket is stopped and a new socket is created for the Game with the message port. When the API receives a message from the Server answering the NEW ROOM message this Room will initiate the Game calling it by a method implemented by the Game:

                                              

·         preInit(ROOM_NAME, USER_NUMBER, MAX_PLAYER);

o   ROOM:   Room Name.

o   USER_NUMBER:  User Id

o   MAX_PLAYER:  Maximum number of players for this Room.

 

When the new socket is launched the API sends a message to the server with the new action. This an ACTION message to the newly created socket. This message reaches the server and is answered to all the Room users.

This message contains information issued by the Game depending on the connected users or if it is the last user to be connected .This is controlled by the Game that should report when a user is connected (MEN_CONECTADO) and when it is the last (MEN_ULTIMO). Optionally it will depend on the game to establish a MASTER or not. This will be explained later in detail.

·         priorWriteAction(MEN_TYPE_BEGIN + : + userId + : + MEN_ULTIMO);

·         priorWriteAction(MEN_TYPE_BEGIN + : + userId + : + MEN_CONECTADO)

 

 

The interval between messages can be established with the variable “limitLatencyToInicio” available in the webVar.js file

 

 

1.2.5.  ACTION Message

This message is in charge of communicating with the Game and with the actions performed in the Game. Starting with this message they will communicate using the API method receivingGameData .

The API communicates with the Game using the method readResponse implemented at the Game.

 

This message received by the Game and contains the movements of the Players.

Message to the Server:

·         function callActionSocketGame (message)

·         ACTION: Type of Message.

·         ROOM_ID;  Room Id.

·         actualMessage: Action Message

·         USER_ID:  Assigned User Id.

·         currentLatency: Player latency.

 

This generates a message to the Server and it is not processed. This message is resent directly to all Room users. The API only sends to the readResponse  method  the actualMessage  which contains the movement action.

 

1.2.6.  actualMessage

This message contains the information with the Players movement.

The message is freely configured by the Game Programmer .Included are examples used when implementing the games presented.

 

 

The separator is “:” .

It includes:

 

·         MEN_TYPE_TECLAS: Action type for all Players except the originator.

·         MEN_TYPE_TECLAS_ALL:  Action type for all Players.

·         userId: Player Id

·         e.keyCode =  Pressed Key

·         posX:  X position of the Player sending the message

·         posY: Y position of the Player sending the message

·         Direction: Moving or Shot  direction.

 

With this information the Game must perform the corresponding actions to implement the users (foe). This will be explained later in Section 3 “Use of the API”.

 

1.2.7.  END SESSION Message

 

This message is sent when a user finishes the session. All users must leave the Room and return to Room Menu.

 

Message to the Server:

·         function callEndSocketGame ()

·         END_SESSION: Message  Type .

·         APP_ID; Application id (Game).

·         ROOM_ID: Room  id.

·         USER_ID: User id.

 

This generates a message for the Server . The Room is deleted and the Socket is stopped . A message is sent to the API with the following info retransmitted to all Rom users.

·         MEN_END

After this the process starts again sending the start message to update the Room list. The Game must include a method endSala() which will enable reinitiating the Game.

 

 

2.           API Use

 

The API supports the Game Programmer implementing messaging tasks with the server and the network parameter control. The Programmer should implement and call different methods to enable a correct communication with the API.

 

Methods to be implemented:

·         function preInit(String pRoom, String pUser, String pNumUser)

·         function readResponse(String pData)

·         function endSala()

Methods to be called:

·         function writeAction(message)

·         priorWriteAction(String pMen);

2.1.    Methods To be Called

2.1.1.  writeAction  method

 

This method is in charge of sending the messages. The method will send the message if the latency allows it. If a 0 is returned the action will be performed because the message has been sent. If a 1 is returned one has to wait or resend the message.

 

2.1.2.   priorWriteAction method

 

This method will send the message like the previous one but will not take into account the latency or other network limitations .Should only be used for priority messages.

2.2.    Methods to be implemented

2.2.1.  preInit method

 

This method is called by the API when a Game is started. For both cases if a new Room is started or if a Player enters an available Room the process is the same. As explained above the Game must perform the corresponding actions to initiate the Player reported by the API. 

 

In this method the Game could for example  analyze the Player and decide whether it needs to issue screen messages.  The Game must issue a message using the method “priorWriteAction” to find out if the Player has connected correctly or if it is the last Player this can be implemented as below:

 

 

if (pUser == maxSess) {    //Eres el ultimo

       priorWriteAction(MEN_TYPE_BEGIN + SEP + userId + SEP + MEN_ULTIMO);      

}  else {                  //Me conecto y se lo digo a los demás  

       priorWriteAction(MEN_TYPE_BEGIN + SEP + userId + SEP + MEN_CONECTADO);    

}

 

When the message returns the method “readResponse” it will be possible to find out if the connection was Ok or if it is the last player.

Parameters:

·         pRoom:  Room connected to.

·         pUser:  User

·         pNumUser: Maximum number of players for this Room.

2.2.2.  readResponse Method

 

This Method is in charge of receiving the API messages arriving from the Server. It is in charge of managing these messages and of performing the corresponding actions.

This method receives a message, a  String  in simple format separated by “;”  following the order specified in the “actualMessage” section 2.2.6.  The format has been explained there and the information is extended in this paragraph. This message can be configured freely by the user and depending on its content it will be returned by the method readResponse. In the following list the ones used in the examples are included. The information could include the Players movement using separator “:” with the following parameters that will reach the method:

 

·         Message Type:

o   MEN_TYPE_BEGIN = "01";  

o   MEN_TYPE_TECLAS = "02";

o   MEN_TYPE_JUGAR = "03";

o   MEN_TYPE_TECLAS_ALL = "04";

·         userId:   Player Id   for the Player moving or performing an action.

·         e.keyCode =  Key pressed by the Player

·         posX:  X position of the Player sending the message

·         posY: Y position of the Player sending the message

·         Direction: Moving or Shot  direction.

 

 

 

The message MEN_TYPE_BEGIN indicates that the User has sent a Begin and wants to start. MEN_CONECTADO indicates a connection and in this case a new player is connected to the Game.

If required a message can be issued by the game programmer. In the case of last user (MEN_ULTIMO)  a message “priorWriteAction(MEN_TYPE_JUGAR + SEP + MEN_JUGAR);” is sent. This message will be sent by the server to all players and the message MEN_TYPE_JUGAR will reach everyone.

When the message MEN_TYPE_JUGAR arrives the Game may start.

The message MEN_TYPE_TECLAS is used when the players perform a movement using the parameters described above. It is used to send the keystrokes this message is sent to everybody except oneself.

The message MEN_TYPE_TECLAS_ALL arrives when the player performs a movement as described above it is used to send the message to everybody including the originator.

Method example:

function readResponse(data) {

                var messageData = data.split(SEP);

               

                if (messageData[0] == MEN_TYPE_BEGIN) {                      //Message type BEGIN

                               var idCon = parseInt(messageData[1]);                               //User connected

                               var men = messageData[2];                                      //Begin message

                                                                                                                            

                               if(men == MEN_CONECTADO){                                               //Connected

                                               if(idCon != idUltimoConectado){             //It is attended if the Id is different from the last connected.

                                                               idUltimoConectado = idCon;

                                                              

                                                               numUsuarios = numUsuarios + 1;

                                                              

                                                               if(MASTER){

                                                                              messageGeneral = "Waiting for other participants to join the Game. Now  connected  " + (numUsuarios) + "/" +maxSess;            

                                                               } else {

                                                                              messageGeneral = "Esperando Oponentes. Conectados: " + (numUsuarios) + "/" +maxSess;              

                                                               }

                                                              

                                                               players[idCon] = new Enemy(idCon);

                                               }                                                                                                                           

                               } else if(men == MEN_ULTIMO){                            //If Last              

                                               if(idCon != idUltimoConectado){             //It is attended if the Id is different to the last user received

                                                               idUltimoConectado = idCon;

                                                              

                                                               messageGeneral = '';

                                                              

                                                               if(MASTER){                                                                                                     //If Master everybody can start the play

                                                                              addListener(document, 'keydown', keyDown);

                                                                             

                                                                              //Play

                                                                              priorWriteAction(MEN_TYPE_JUGAR + SEP + MEN_JUGAR);                              

                                                               }             

                                                              

                                                               players[idCon] = new Enemy(idCon);

                                               }                                                                                                                           

                               }                                                                                                                           

                } else if (messageData[0] == MEN_TYPE_TECLAS) {        //Message with Keystrokes

                              

//Teclas – MEN_TYPE_TECLAS + SEP + userId + SEP + e.keyCode + SEP + posX + SEP + posY;

                               var userIdAux = parseInt(messageData[1]);

                               var keyCodeAux = parseInt(messageData[2]);

                               var posXAux = parseInt(messageData[3]);

                               var posYAux = parseInt(messageData[4]);

                               var direction = parseInt(messageData[5]);        

                               var playerAux = new Object();

                              

                               for(var i=0;i<players.length;i++){

                                               try {

                                                               if(players[i].id == userIdAux){

                                                                              playerAux = players[i];

                                                               }

                                               } catch (e) {}

                               }

                              

                               if(userIdAux == playerAux.id){

                                               doAnythingEnemy(playerAux, keyCodeAux, posXAux, posYAux, direction, userIdAux);      

                               }                                            

                } else if (messageData[0] == MEN_TYPE_JUGAR) {         //Mensaje tipo JUGAR (play)

                               addListener(document, 'keydown', keyDown);               //Keystroke’s info provided

                              

                               messageGeneral = '';

                }

}

2.2.3.  endSala message

 

This method is called by the API when the API receives a message type END_SESSION .This method should have all the required code to restart the Game their variables or any other necessary element.

 

3.           Implementation using Chrome

3.1.    Configuration and download

 

To develop the Game applications the Chrome Developers Version has to be installed Chrome dev channel  at ( https://www.google.com/intl/es/chrome/browser/index.html?extra=devchannel#eula)

The Experimental Extension APIs  have to be enabled using from inside Chrome the address chrome://flags .

Using the Chrome Address chrome://extensions/ the selected unpacked application can be downloaded from our project folder pressing the button  “Load unpacked extension” once accepted the Game is loaded. All these activities require the “Developer mode” activated in this page.

To create a Game using Chrome a skeleton Project is proposed using an IDE (for example Eclipse). The Project uses JavaScript with a similar structure as the BasicGameSkeleton which is available on the repository.

The project has all the necessary components to work with Chrome extensions and includes the following files and folders:

main.js:    Declares the Start Page and its size.

manifest.json: Game Information

inicio.html: Start Page.

css: CSS folder

images: image folder.

Js: JavaScript folder it includes the  API.

 

3.2.    Game Skeleton And Other  Games  Examples

 

Some Game examples are provided in JavaScript using this API. There are I the repository three games one of them is just an Skeleton.  A Cowboys Game , a Pong Game and a basic moving  example game include some documentation with explanations an a tutorial.  These examples show the basic Game elements in the form of Game templates trying to help in the use of this API. The minimum required methods are included and each programmer can freely decide what to add to this methods to implement his particular Game.

The project has all the necessary components to work with Chrome extensions and includes the following files and folders:

main.js:    Declares the Start Page and its size.

manifest.json: Game Information

inicio.html: Start Page.

css: CSS folder

images: image folder.

Js: JavaScript folder, it includes the  API.

.

3.3.    Tutorial Basic Game

 

Initially the JavaScript Project has been created in Eclipse Juno, of course any other IDE can be used as well  including a basic text editor. The Games run Java Script and no compiler is required.

We create the Project, provide a name and create the folders and file structure of the Project similar to that of the Project BasicGameSkeleton it is a simple structure that will work in the Chrome extensions.

We create the folders: css for the css files, folder images for images and folder js for the js files.

In the js folder the Smart Stream API Message Broker should be found. This API includes the library JQuery , the Q4S library ,the Message Broker library , Web and webVar additionally in this folder the designer`s Game files in this case js files have to be located.

The files found at root will be :

 inicio.html , this a simple HTML file with the Game . We import from there the css  and the js .

A simple structure is shown in the example BasicGameSkeleton this could be changed by the programmer , it should contain the essential elements with the corresponding id’s : options, div_salas_insertar, div_salas, nameSala, maxJug, nuevaSala, labelMen, juegoCanvas, canvas, exitSala, idRomm, idPlayer, idLatencia.

Main.js, this file contains information for Chrome indication the start page and the size.

Manifest.json, this file contains also information for Chrome concerning descriptions, versions and icons.

 

With these files we have all that is required to start our Game programming using the API Message Broker with Q4S.

En this example all is included in game.js but each programmer is of course free to create his own classes following his particular needs.

A template is available and we will follow it for this tutorial to implement the Game. It is the  BasicGameSkeleton included in the information package.

We can copy it in our new project. This code will be used to control the game keystrokes . Later a JavaScript variable will be created to control the Game in this variable we will introduce all the methods necessary for the communication with the API and our own.

We will define the game variables, keys, control variables, margins and player variables.

We will define there the required variables needed for the API in order to call them from this point: preInit, readResponse, endSala.

 

 

 

We will define the methods to paint the screen , to access the keys and to control the players.

The implementation of each of them is as follows:

·         preInit:

·         This method will receive the Room Id , the Player Id and the number of players , we save this value in a variable , another control variable is set to true to define when to draw the preloaded images ,start the Game canvas or create the animation.

·         Loading with the obtained data the HTML labels and start the Players.

·         iniciarJugadores:

In this method it is shown a way to initialize the players keeping he Player Id ,  1 corresponds to the MASTER . Game messages are issued and local player is started . It is possible here to start the animation. In case of a different player (not the MASTER) we provide the received Id to the localplayer and fill in the rest of the players in an array with animations and messages. Depending on the user being the last  or not,  the corresponding messages have to be sent to the API via “priorWriteAction”.

·         readResponse:

The message arriving from the Server could correspond to various cases .If it is MEN_TYPE_BEGIN this means that a user is connected. If this is not the last user,  it is inserted in the players array . If it were the last user (MEN_ULTIMO) a message is sent to the API declaring that the last player has connected and the player is saved. If the message is MEN_TYPE_JUGAR then the kestrokes are sent and the Game is started. If the message is of the type MEN_TYPE_TECLAS the corresponding action is implemented for example if  the keystrokes correspond to the action move  n player according to the message , the variables are extracted from the message and the action is implemented .

·         endSala:

This method is called when any user finishes the game. The message should contain the information required to restart the Game, the keystrokes are discarded the end game messages are issued and the corresponding variables are reinitialized.

·         keyDown:

The programmer can use any method to capture keystrokes in this example addListener is used. The movements of the Players have to be allowed by the API . The next position of the player is calculated and a message to the server is prepared including the message type , player Id  to be moved , the keystroke , the positions and the intended moving direction. This message is sent with writeAction. If a 0 is returned the movement takes place if not the movement is cancelled.

·         LocalPlayer:

This method defines the local player margins, the starting image and address and Id  and provides position image and speed as defined above.  The method doAnything defines its movement.

·         Enemy:

Similar to the previous method only in this case the method doAnything is implemented outside in order to control it from readResponse.

 

Once the code is ready the programmer accesses the SSMB network to register the application using a Game Name and specifying a maximum number of users .  Once saved an Id is provided identifying the Game Application that has to be used in the API  webVar to identify the Game inserting it in the file webVar.js assigning the variable APP_ID supplied by the Platform.

Loading the Game :

To load the Game application use the Chrome Developers Version see Paragraph 4.1

The Experimental Extension APIs  have to be enabled navigating from Chrome to the address chrome://flags .

Using the Chrome Address chrome://extensions/ the selected unpacked application can be loaded from our project folder pressing the button  “Load unpacked extension”. Once accepted the Game is loaded. All these activities require the “Developer mode” activated in this page.

Once loaded the Game appears in the list of extensions as an icon and can be launched selecting it.

Content