$
]
{
}
<
{

NOUS LES DEVS

Système de reconnexion

A la conquête du jeu vidéo partie 15

Niveau : expert(e)
</> </> </>

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 -

NOUS LES DEVS

Vous aimez ce que je fais ? Vous voulez que j'en fasse plus ? dans le développement du blog.