JeuWeb - Crée ton jeu par navigateur
[Brainstorming] comment créer la relation client-serveur? API ? Socket? - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : [Brainstorming] comment créer la relation client-serveur? API ? Socket? (/showthread.php?tid=3294)



[Brainstorming] comment créer la relation client-serveur? API ? Socket? - Maz - 25-07-2019

Salut tout le monde!

Je cogite, chaque jour à la manière dont je vais développer mon prochain projet. Je me remet dans le bain après quelques années et je (re-)découvre quelques trucs.

Mon dernier vrai projet en date est de 2011 :bye: , c'était un jeu débuter en PHP puis transféré en Ruby. Et à l'époque c'était du coding sur le tas: le joueur cliquait un bouton pour lancer la construction, ça rafraîchissait la page pour enregistrer la requête SQL, un peu de js pour un minuteur et basta!

Je lis énormément en ce moment sur les nouvelles techno. Et je vois qu'aujourd'hui, les app sont vraiment structurées en "client-serveur".

J'ai lus quelques articles sur les API REST et je me posais la question : ce type de procédé peut il être utilisé pour le côté serveur?

Mon jeu, pour le côté client sera (sûrement, ça peut changer d'ici le commencement de la mise en prog') développer en PHP avec Symfony, en application "one page" avec Vue.js.

Mais pour le côté serveur?? Je sais que Symfony permet de faire des API. Mais de ce que j'ai lu, les API sont a la base créé pour permettre à d'autres de lancer certaines requête sur notre serveur. Mais il est probablement possible de sécuriser pour ne permettre que des requêtes internes.

Mes questions sont: comment faites vous la relation entre le client et le serveur? Je pourrais aussi utiliser des sockets avec Vue.js mais j'ai pas encore mis le nez dedans donc je ne sais pas quelle solution est la plus viable.

Merci pour vos éclaircissements.


RE: [Brainstorming] comment créer la relation client-serveur? API ? Socket? - Sephi-Chan - 25-07-2019

Depuis que je fais des single page apps (dans mon cas en React plutôt qu'avec Vue), je n'utilise plus trop d'API REST. A la place, j'utilise WebSocket pour des communications bilatérales en temps-réel, avec une couche d'abstraction qui permet l'utilisation de channels.

J'utilise bien sûr toujours JSON pour la sérialisation des données échangées entre le client et le serveur.

Une API qui passe par HTTP (RESTful ou non) peut tout à fait être utilisé par d'autres services (on utilise généralement un protocole comme OAuth pour la gestion des permissions), mais dans ton cas, le site de ton jeu sera le seul consommateur de l'API (au moins au début) : tu lui enverras des requêtes asynchrones (via XMLHttpRequest, Ajax quoi), elle te retournera du JSON, tu t'en servira pour faire muter l'état de ton app Vue, etc.

Tu peux aussi mélanger les deux : faire des requêtes Ajax et recevoir des push du serveur par WebSocket, quand une tâche de fond du serveur signalera la fin de la construction d'un bâtiment ou une unité.


RE: [Brainstorming] comment créer la relation client-serveur? API ? Socket? - niahoo - 25-07-2019

(j'avais fait un brouillon avant la réponse de Sephi mais j'ai fini mon épisode avant de poster, donc il y aura des redites)

Citation :Mais il est probablement possible de sécuriser pour ne permettre que des requêtes internes.

Ici par API on entend simplement que le serveur ne te renvoie que des données, par exemple du JSON ou du XML, et c'est ton code javascript seul qui se charge de présenter ces donneés, donc de gérer le HTML.

Ça ne change rien au fait que le code serveur est le tien, tu fais ce que tu veux des requêtes que tu reçois. Simplement tu utilises un format de données générique plutôt que de devoir traiter tes données différemment ce que tu veux afficher. Ça simplifie pas mal la partie serveur et permet d'isoler les choses.

Le javascript devient plus indépendant et tu peux mettre des event handlers où tu veux directement avec des fonctions au lieu de mettre des données un peut partout dans le DOM. Le DOM n'est pas un espace de stockage pour l'état.

En contrepartie ton javascript se complexifie pas mal. Vue n'est pas ma tasse de thé mais j'ai pratiqué pas mal et ça fonctionnera bien.

Pour un jeu, je n'utiliserais pas REST, mais RPC, et comme Sephi je le fais au travers d'un websocket car j'ai des processus qui prennent un certain temps sur le serveur (par exemple 30 secondes, le temps de construire un bâtiment) et c'est plus simple d'envoyer un nouvel état depuis le serveur plutôt que de gérer aussi des timers côté client pour rafraîchir la vue. Mais ça nécessite forcément une architecture serveur plus conséquente. Ce n'est cependant pas indispensable, surtout si tu (re)débutes et que tu pars logiquement sur un projet plutôt simple.


RE: [Brainstorming] comment créer la relation client-serveur? API ? Socket? - Xenos - 28-07-2019

Nota que Websocket ou assimilé seront souvent coupés sur un mutualisé, le choix de l'archi ira donc certainement de paire avec le choix de ton hébergement (ou à l'inverse, la contrainte d'hébergement contraindra l'archi)

Pour ma part, je considère que le web est fondamentalement basé sur la notion de "document", ce qui signifie qu'il n'y a pas lieu de séparer les API REST de la mécanique classique des pages. Dit autrement, un "site classique avec des pages HTML" c'est ni plus ni moins qu'un serveur API qui répond un document formatté en HTML. Conséquence de quoi, sur ECLERD (ou Variispace mais n'étant pas en ligne tu auras du mal à le tester), chaque point d'entrée du serveur web (endpoint) construira un modèle de données (via une procédure stockée le plus souvent) et répondra ces données formattées comme le client l'a demandé (via son head HTTP Accept, ou via le paramètre GET non standard "http-accept"). Donc typiquement, la page https://eclerd.com/map/mapcase/?id=5581 sera requêtée par le navigateur avec un Accept header "text/html" (par défaut du navigateur). Mais si un client (JS, navigateur, whatever) requête https://eclerd.com/map/mapcase/?id=5581&http-accept=application/json (ou met son application/json dans son HTTP Accept header), alors le serveur répond les données formattées en JSON. https://eclerd.com/map/mapcase/?id=5581&http-accept=application/json est aussi accepté (à désérialiser avec PHP). Ou encore, http-accept=application/vnd.oasis.opendocument.spreadsheet (je viens de voir que la page map/mapcase plante sur ce format, il faudra que je regarde en détail le ticket associé), que je trouve "fun" car il me servait juste à montrer (au taff) qu'on pouvait faire des exports excel instantanément et sans ajouter des tonnes de code (et si tu enregistre le fichier et que tu as open office/excel, tu devrais voir la Terre en guise d'icône de fihcier; là aussi, c'était pour le fun).

Je ne vois pas comment développer un "côté client en PHP avec Symfony"?! Et "le DOM n'est pas un espace de stockage pour l'état", ça me fait ticker, puisqu'on parle de Document Object Model (dont la définition est maintenant chez les WHATWG je crois https://dom.spec.whatwg.org/ ). Après, oui, si on veut refaire Unreal 2019 dans le DOM, ça va trimer.

Citation : Mais il est probablement possible de sécuriser pour ne permettre que des requêtes internes.
Soit je n'ai pas compris, soit la réponse est non. Si un client tiers doit faire des requêtes sur ton serveur (ie: un navigateur, que ce soit avec du HTTP classique, du "REST API JSON" ou du websocket) alors il aura la main pour voir comment sont faites ces requêtes, et les triturer. Ou alors, tu veux que ton serveur fasse des requêtes vers... ton serveur? Auquel cas, c'est une énorme perte de temps d'exécution (pour rappel, en gros, c'est x10 par niveau: mémoire processeur = 1ms, accès RAM = 10ms, accès disque = 100ms, accès réseau = 1s, ok, maintenant, tout est divisé par 10, mais les ordres de grandeurs relatifs restent les mêmes). Donc en gros, à part faire plus lentement (et probablement moins sûrement) ce que tu veux faire, je ne vois pas l'intérêt d'appels serveur-serveur?


RE: [Brainstorming] comment créer la relation client-serveur? API ? Socket? - Sephi-Chan - 28-07-2019

Il y a plein d'URL dont avoir une représentation HTML n'a aucun intérêt.

Dans une application cliente riche complexe, stocker des infos (et les maintenir) dans le DOM (dans des attributs, notamment) est possible mais c'est vite très peu pratique et mène souvent à de gros problèmes de performances. Ça marche mieux quand tu stockes les données dans des variables Javascript.


RE: [Brainstorming] comment créer la relation client-serveur? API ? Socket? - Xenos - 29-07-2019

Hum, ça dépend, je serait curieux de savoir quelles URLs n'auraient strictement aucun intérêt à être aussi formattables en HTML. Les URLs des soumissions des formulaires par exemple sont également appelables en HTML sur ECLERD. Le HTML se contenant alors juste d'être la version formattée du bean "title+message" de la réponse du formulaire (fais le test si tu veux: clic droit sur le cadre "Législation", ouvre-le dans un nouvel onglet, puis bloque JS via noscript ou autre extension du style, et clique sur le "promulguer" des lois de ton pays sur ECLERD: tu récupères la page de réponse du formulaire formattée en HTML)

Franchement, l'argument des perfs m'a été servi tellement de fois que je n'ai plus envie de m'attarder dessus au-delà de "teste et tu verras que les perfs seront souvent suffisantes" (hors "je réinvente AOE2/UT2004 dans le navigateur", comme dit). Quant à la practicité, les API DOM sont parfaitement fonctionnelles pour ça, donc perso, je trouve que se palucher des brouettes de dépendances/FW pour essayer vainement cascader magiquement l'état des variables JS dans le DOM, c'est bien plus lourdingue que de considérer que le DOM fait foi et d'aller piocher ses infos dedans. Après, ça dépend sûrement des jeux, mais pour ceux que je vois passer ici (et pour 99% des sites du web environ), c'est largement suffisant, fiable et simple.


RE: [Brainstorming] comment créer la relation client-serveur? API ? Socket? - Sephi-Chan - 29-07-2019

Je sais qu'on avait des avis assez divergents sur ce qu'était une bonne expérience de jeux dans le navigateur. Je rappelle ma position : dans le cas d'un jeu, je pars du principe que Javascript est disponible, je ne veux pas que ça ressemble à un site mais à un jeu (avec des bouts de site dedans si j'ai besoin de trucs plus standards), j'oublie les formulaires (sauf pour des entrées texte) et les rechargements de page.

Pour l'aspect pratique, je ne sais pas si tu as déjà codé des SPA, mais le faire à la main avec le state dans le DOM devient impossible à maintenir très vite. J'en ai fait à la main, avec Backbone, avec React. C'est très sympa d'utiliser du DOM et des events handlers pour de petits composants interne à la page, mais mais ça s'arrête là.


RE: [Brainstorming] comment créer la relation client-serveur? API ? Socket? - niahoo - 29-07-2019

Citation :Quant à la practicité, les API DOM sont parfaitement fonctionnelles pour ça, donc perso, je trouve que se palucher des brouettes de dépendances/FW pour essayer vainement cascader magiquement l'état des variables JS dans le DOM, c'est bien plus lourdingue que de considérer que le DOM fait foi et d'aller piocher ses infos dedans. Après, ça dépend sûrement des jeux, mais pour ceux que je vois passer ici (et pour 99% des sites du web environ), c'est largement suffisant, fiable et simple.

Non, juste non. Pour avoir bossé sur une appli ou le DOM était utilisé pour stocker l'état de la page, à base d'attributs foireux, d'input hidden ou de formulaires complets masqués, quand le DOM fait foi c'est généralement dégueulasse : les mecs stockaient les arrays sous forme de listes à virgules, les booléens sous forme de "yes" "no" "trUe/fAlsE", pour des maps c'était plusieurs inputs, etc.
J'ai développé des modules sur cette appli en stockant mes données dans un objet JS et en mettant à jour le DOM en fonction des données, sans avoir à "lire" le DOM.
Et comme par hasard ça prenait 10 fois moins de temps à maintenir, débugger, évoluer ; notamment parce que beaucoup plus court. Et ce, sans aucune dépendance JS hormis quelques helpers MooTools (un jQuery-like qui était présent sur toutes les pages), pas de packages npm, de compilation ou de framework qui dicte comment organiser ton code.

C'est pas un problème de perfs mais d'hygiène, et ça peut se faire nativement. Invoker la lourdeur des frameworks est hors-sujet.

Je me suis simplement inspiré (très largement) de d3js, bien avant que Facebook sorte Flux et prétende l'avoir inventé Smile

Alors oui les autres devs n'étaient pas très bons (sans me la péter) et auraient pu mieux faire tout en gardant le DOM comme stockage de l'état, mais pour moi ça reste une solution simpliste. Par exemple quand tu as des données que tu ne veux pas représenter tu vas commencer à mettre des display none, des input hidden, ce genre de trucs, c'est vraiment moche.