GL-MPRI-2014 / Ocawai

OCAWAI
8 stars 3 forks source link

Dé-marshalisation #137

Open Mazzocchi opened 9 years ago

Mazzocchi commented 9 years ago

J'ouvre ce ticket car j'ai commencé à réfléchir sur ce sujet. Si d'autre personne s'y joignent qu'il fasse part de leurs avancés et de leurs remarques.

dbusatto commented 9 years ago

J'ai pas suivis ce qui c'est dit sur marshall mais si je ne me trompe pas c'est pour sérialiser les objets c'est ça?

Si oui je peut facilement ajouter a config des méthodes Tile.t -> char et char -> Tile.t (ça ça existe déjà en fait), Unit.unbound_t -> char et char -> Unit.unbound_t (même principe)

Unit peu facilement se voir rajouter des méthodes Unit -> Unit.unbound_t * Pos.t * Player.id * int et inversement (Pour ceux qui n'auraient pas suivi unbound_t de Unit c'est la classe d'une unité moralement, c'est ce qui est paramétré en config)

Battlefield possède déjà des méthodes Battlefield.t -> string et string -> Battlefield.t

Toutes ces méthodes supposent que la config des tuiles et des unités ainsi que les settings communs engine-interface soient les même coté client et serveur, il serait donc judicieux d'appeler des éventuelles méthodes Config.init_(tiles/nbound_units)_from_string : string -> unit coté client en leur passant des versions sérialisées des tuiles et unités du serveur, récupérée au début de l'échange (atdgen fournit déjà des (dé)sérialiseurs)

Si ça vous intéresse c'est vraiment rapide a faire de mon coté donc n'hésitez pas a le dire et je rajouterai ces méthodes à master

Mazzocchi commented 9 years ago

Effectivement ça sert à ça, l'objectif étant d'être plus portable. Très bien merci.

dbusatto commented 9 years ago

Voilà, c'est fait!

Au début, utiliser les méthodes string_of_tiles_list, string_of_unbound_units_list, et string_of_settings de Config.config sur le serveur pour obtenir trois strings, les envoyer au client, qui utilise Config.config#load_from_strings pour les charger

Ensuite, on peut utiliser Config.config#string_of_battlefield et battlefield_of_string pour s'envoyer la map, et Config.config#string_of_unit et unit_of_string pour créer coté client des instances d'unités identiques à celles côté serveur.

Après ça on peut se servir des ids des unités dans les updates

dbusatto commented 9 years ago

par contre, les strings créés par les méthodes ci dessus contiennent potentiellement tout charactère de \0 à \255, faudra faire gaffe si le réseau utilise des caractères spéciaux en délimiteurs

Mazzocchi commented 9 years ago

C'est bien comprit. Je pense que l'on va faire quelque chose de semblable au projet de RESEAUX mais en bien plus minimaliste.

Mazzocchi commented 9 years ago

Je viens de terminer l'implémentation des fonctions 'send' & 'recv' pour la dé-marchalisation. Ce qui transit est donc de la forme : magic (1 byte) || length (4 bytes) || data ... Où magic sera un entier provenant d'une énumération de tout les types de fonctions qui passe pas le réseaux. Si je me souvient bien il y a : get_next_action update error Ce type n'est pas encore crée !

dbaelde commented 9 years ago

@Mazzocchi est-ce que les types que tu décris ne seraient pas Types.send et Types.receive? sinon je ne comprends pas ton message.

Mazzocchi commented 9 years ago

Le type que j'ai décri est une représentation par énumération de l'union des types " Types.send " et " Types.receive ". En C ça donnerais : typedef enum { Get_next_action, Update, Next_action, Error } magic_t;

Mais étant donné ce qui a été fait, il serait plus judicieux d'avoir : typedef enum { Get_next_action, Update } magic_send_t;

typedef enum { Next_action Error } magic_receive_t;

Cependant je trouve particulièrement naze de voir apparaître les termes " send " et " recv " dans des noms de types puisque tous peuvent être envoyé et reçu ...

Mazzocchi commented 9 years ago

@juliengrange : Il faudrait que tu fasse un tour du coté du "dealer" et du "netPlayer". J'ai mis du code en commentaire (que tu ne pourra pas louper) !

juliengrange commented 9 years ago

C'est bon, j'ai pushé dans la branche player, tu peux y jeter un coup d'oeil. Pour faire simple :

Par contre, je n'ai pas compris quel était ton projet de "kill the player" dès qu'il ne répond pas en moins de 3 secondes. C'est un peu dur quand même, non ? D'ailleurs je ne sais pas exactement ce que tu entends par "kill the player". Si tu veux modifier ces passages pour faire à ta sauce, j'ai laissé les commentaires...

Mazzocchi commented 9 years ago

Super !! Trois secondes, j'ai mis ça au hasard, il faudra paramètrerp plus tard, en attendant tu peux choisir ce que tu veux. KILL THIS PLAYER : Je t'explique, si le player se fait timeouter alors qu'il n'est pas mort, il risque d'y avoir des résidus d'envois en cours qui planterait le moteur. Donc, un timeout = une défaite !

dbaelde commented 9 years ago

@juliengrange as-tu oublié de push? @juliengrange et @Mazzocchi avez-vous pu tester le client/serveur avec le nouveau protocole? les déconnexions brutales (mort subite d'un client) sont-elles mieux gérées qu'avant?

juliengrange commented 9 years ago

Si, j'avais pushé... Je ne comprends pas ce qui s'est passé (d'autant que l'historique du projet le mentionne) Enfin le problème est réglé...

Edit : pour tester le protocole efficacement, il faudrait implémenter les fonctions to_string et from_string dans Action et Types. Sinon je suppose que Mazzochi a testé ses fonctions send et recv... (je n'ai pas pris la peine de vérifier qu'elles fonctionnaient)

Mazzocchi commented 9 years ago

BUG ! J'ai compris ce qui n'allais pas dans le protocole réseau, je profite d'un instant de connexion pour en parler. Dans la branche client, module send_recv le read de recv_string à un problème : Il annonce qu'il à reçu 'x' octet(s) mais le buffer reste vide ... J'ai mis beaucoup de logs qui permette de comprendre. Ainsi, lorsqu'on test, le serveur envois un get_next_action, les clietns reçoivent quelque chose mais le buffer reste vide, l'entier magic (code pour le get_next_action) est une chaine vide -> Ils meurt donc un à un. Je ne comprends pas se bug et je sais qu'il tient le fonctionnement puisque c'est ce qui fait échouer le int_of_string (celui du magic donc).

Mazzocchi commented 9 years ago

Le bug était bidon en fait. Je ne sais pas trop où en est @juliengrange mais il me semble que le protocole soit opérationnel de mon coté. La question plus clairement posé est où en sont les fonctions to_string et from_string ?

Mazzocchi commented 9 years ago

Je souhaiterais savoir ou en sont les fonctions from_string et to_string (de @juliengrange) ?

juliengrange commented 9 years ago

Elles sont écrites. Depuis jeudi dernier, j'ai décommenté le code qui avait besoin de building_of_string, j'ai ajouté le constructeur Config à Types (pour permettre au client d'obtenir les même paramètres de configuration que le moteur), et j'ai modifié les caractères spéciaux en '\000' et '\001' (sauf pour Map, qui n'en a pas puisque tout les caractères sont utilisés dans string_of_map).

En gros c'est prêt à être utilisé.

Mazzocchi commented 9 years ago

Je suis plutôt content ; Tu a fait des tests ?

Mazzocchi commented 9 years ago

Il faudrait implémenter la fonction kill_client détruit proprement un joueur (notamment avec un close sur la socket).