Administratorfriendly
Précédemment, j’ai créé un outil qui permet de sauvegarder et restaurer des parties, mais les déconnexions du client ou l’extinction du serveur pose toujours problème et me demande quand même certaines manipulations, et j’aimerais automatiser toute cette partie, ou du moins rendre ça plus « administratorfriendly ».
Extinction serveur
Dans la partie 4, quand j’ai abordé le temps réel, j’avais ajouté l’événement « disconnect » au niveau du client, tu te souviens ? C’est un événement qui est déclenché lorsque le serveur s’éteint. Maintenant, dès qu’il va s’éteindre, je vais simplement ré-afficher la zone #serveur_info au niveau de l’interface et bien sûr, avertir le joueur que le serveur est en vacances.
this.socket.on('disconnect', () => {
e("Le serveur à été déconnecté");
this.go_to("home");
$("#serveur_info .message").html("Le serveur n'est pas connecté, merci de votre patience....");
$("#serveur_info").show();
});
Reconnexion serveur
Lorsque le serveur va redémarrer, juste avant de faire l’init (au niveau du constructeur) je vais lancer une restauration des parties, et lorsque la promesse est résolue, alors j’initialise mon serveur HTTP.
//restauration partie
this.restore_parties().then( (response) => {
e("> Parties récupérés");
this.parties = response[0].json_data;
//initialisation http
this.init();
});
Et ce qui est bien, c’est que grâce à socket.io la reconnexion du serveur est détectée automatiquement, et l’événement « connect » va relancer tout le process de login dans la foulée.
Reconnexion client
Dès que le client va se reconnecter, je vérifie si son token est présent dans l’une des parties, si c’est le cas, alors j’actualise ses données.
set_token(user_socket, params){
//...
//recuperation de la liste des parties et verification si joueur présent
for(let id_partie in this.parties ){
//si le token joueur est présent dans la liste des parties, alors recréer l'user
if( Object.keys( this.parties[ id_partie ].list_players ).indexOf(params.token) >= 0 ){
///mise à jour utilisateur
this.users[ params.token ] = {
connected : true,
socket_id : user_socket.id,
state : "fight",
last_token : params.token,
current_partie : id_partie
};
break;
}
}
//this.users[params]
if(this.users[ params.token ] == undefined ){
//...
}else{
//si le joueur etait en combat
//reconnexion de combat
if( this.users[ params.token ].state == "fight"){
response_params.state = "fight";
response_params.aquiletour = this.parties[ this.users[ params.token ].current_partie ].courant.aquiletour;
response_params.players_index = this.parties[ this.users[ params.token ].current_partie ].list_players[ params.token ].index;
response_params.jour = this.parties[ this.users[ params.token ].current_partie ].courant.jour;
response_params.money = this.parties[ this.users[ params.token ].current_partie ].list_players[ params.token ].money;
response_params.result = true,
response_params.map = this.parties[ this.users[ params.token ].current_partie ].map;
response_params.go_to = "map";
response_params.units = this.parties[ this.users[ params.token ].current_partie ].courant.units;
}
}
//...
}
Réponse
Je dois bien sûr mettre à jour la méthode response_set_token, et en fonction de l’état du joueur, rebinder toutes les actions ou relancer la partie, si le joueur était en combat.
response_set_token(params){
//...
if(params.connected){
//si user libre ont refresh
if(params.state == "free"){
//refresh list map
this.update_list_map(params.list_maps);
//refresh list partie
this.list_parties = params.list_parties;
this.refresh_list_parties(params.list_parties);
//bind click step creation et joindre partie
$(".option #option_create_partie").bind("click.menu", () => {
$("#menu .step").hide();
$("#menu .option_step_create_partie").show(300);
//click return home
$(".option_step_create_partie .go_home").click( () => {
$("#menu .step").hide();
$("#menu .option_step_home").show(300);
});
return false;
});
$(".option #option_join_partie").bind("click.menu", () => {
$("#menu .step").hide();
$("#menu .option_step_join_partie").show(300);
//click return home
$(".option_step_join_partie .go_home").click( () => {
$("#menu .step").hide();
$("#menu .option_step_home").show(300);
});
return false;
});
}else if(params.state == "fight"){
this.response_launch_partie(params);
}
}
}
Déconnexion client
Pour traiter le cas de la déconnexion d’un joueur, c’est beaucoup plus simple ! Le seul cas où c’est problématique c’est lors de la création ou de la validation d’une partie, si jamais un joueur se déconnecte pendant l’une de ses phases, ben ça le fait pas trop pour les autres joueurs de la partie, donc mon idée c’est de faire comme si le joueur avait cliqué sur le bouton « Quitter la partie » en simulant ça au niveau du serveur grâce à la méthode request_quit_partie.
init_io(){
//ecoute
this.io = lib_socket_io.listen(this.http_server);
//detection de connection
this.io.sockets.on('connection', (user_socket) => {
//...
user_socket.on('disconnect', (params) => {
e("> Déconnection");
let user = this.get_user_by_socket_id(user_socket.id);
if( user == undefined){
//cas d'un user debug
return false;
}
this.request_quit_partie( user_socket , { token : user.last_token , partie_id : user.current_partie } );
});
});
}
08/09/2016
Yann Vangampelaere - nouslesdevs -