Skip to content

3. Socketio server

Manousos Linardakis edited this page Aug 27, 2023 · 1 revision

SocketIO Server

3.0 Flask-Socketio Server

socketio logo

The web simulator's backend is powered by a Flask-SocketIO server, which uses rooms and sessions to ensure that messages are directed to the appropriate simulator tab.

3.1 Local execution of server

To run the server locally and establish a connection to the simulator, navigate to the exports directory of the source code for the web simulator and execute the following command in your terminal:

python3 server.py

This will launch a SocketIO-flask server locally. You can then access the simulator by visiting the http://localhost:8000/godot or http://localhost:8000/godotcode in your web browser. You can then start exploring the simulator's functionalities!

All the files required for deployment can be found in the exports folder. Simply download the contents, run the server as described above, and you'll be ready to test the simulator.

  • Note: If you want to connected to distant server, go to address: server_address/godot or server_address/godotcode.

3.2 Socketio Session

The SocketIO server efficiently handles multiple user interactions by generating a new session using Universally Unique Identifiers (UUIDs) each time a new tab is opened in the web browser. This session ID is not only unique but also serves as the room name, providing a distinct simulator instance.

Fullscreen Tab Fullscreen Tab of the Simulator.

To connect to a specific simulator associated with a particular tab, users must copy the corresponding session ID and use it as an attribute in the developed client classes to establish the connection. This approach ensures that each user can interact with the simulator instance specific to that tab. Like so, the web simulator allows users to create and manage multiple simulators, with each instance having its own unique session ID.

Many fossbot levels Example of multiple simulator instances - sessions.

Upon user connection to a session, the SocketIO server stores the user_id within that session. This information is important for the disconnect method to ensure proper handling of user disconnection from the server.

3.3 SocketIO Rooms

socketio rooms

Image from the official SocketIO documentation here.

The SocketIO server incorporates the concept of "rooms" to tailor the user experience and maintain a personalized connection environment. Each room is uniquely identified by a name, which is equivalent to the session_id declared by the server. Within each room, there exists a single simulator instance and multiple clients that have control over this specific simulator.

This room-based architecture ensures a distinct and isolated space for each simulator, allowing multiple users to interact with different fossbot simulations simultaneously. By segregating the users into separate rooms, data exchange between users from different rooms is prevented, safeguarding the integrity and privacy of each simulation.

3.4 JSON messages

json logo

The communication between the client and the simulator is facilitated through JSON messages, each containing specific attributes corresponding to the intended function. The majority of JSON messages sent by the client include an attribute named func, which declares the function to be executed.

3.4.1 Multiple Fossbot Control

Additionally, for fossbot functions, there is an attribute called fossbot_name, specifying the name of the fossbot that will execute the function. Like so, the message reaches the correct fossbot instance, facilitated by the foss_handler node.

  • Note: For the Godot Environment user, which is responsible for changing the environment and spawning things, a fossbot name is not an attribute of the socketio message. You can view the godot environment user only in python library here.

3.4.2 Simulator Response

In response to client messages, the simulator sends JSON messages back to the client. These messages can either contain the desired answer to a GET function or an error notification. In case of an error, the simulator transmits it to the godotError route of the SocketIO server. Conversely, for successful execution, a regular message is sent to the godotMessage route of the SocketIO server.

3.4.3 Fossbot Response

With the implementation of multiple fossbot instances, the data is sent to the specific user who has connected to the respective fossbot (only one user can connect to a fossbot model at a time) directly from the fossbot model and not from foss_handler. To achieve this, the SocketIO's built-in user_id feature is utilized. This unique identifier is assigned to users upon connecting to the server. Subsequently, the emit function of SocketIO is employed, with the to attribute specifying the user_id, thereby ensuring precise delivery of the message to the intended user. This mechanism guarantees a personalized fossbot function execution for the connected users.

3.4.4 Communication Schema

socketio comm

3.5 Godot Connection to SocketIO

godot socketio comm

As SocketIO is not natively supported in Godot, a workaround was implemented. The Godot simulator connects to the SocketIO server using JavaScript.get_interface("window"), a method available in Godot. This function enables the execution of JavaScript functions within the frontend window. For more information about this method see the godot docs.

By utilizing this bridge, the JavaScript function executes the connection to the server. When a message is received (using the clientMessage route), a callback is triggered back to Godot, facilitated by the create_callback method of godot (more details about this method here). This callback then sends the data to the foss_handler node, which, in turn, dispatches it to the appropriate fossbot, enabling seamless concurrency.

This integration allows the web simulator to operate efficiently and provides a smooth experience for users interacting with multiple simulations and fossbot instances concurrently.

3.6 Client disconnect

Upon user disconnection from server, a disconnect message is transmitted to the server. The user_id that was assigned from the socketio in the beginning (and saved in the session of the client) is then sent in the json message of the disconnect. Additionally, the func attribute of the disconnect message is set to exit_func. This specific function, exit_func, is responsible for stopping and resetting the fossbot. Moreover, it ensures the proper removal of the user from the simulator, effectively freeing the connected fossbot for other users to control.