Ruby est-il viable pour coder un serveur de jeu ?

Parce que s'il faut tout recommencer, je préfère le faire dès maintenant...

Le problème exposé dans ce sujet a été résolu.

Bonjour,
Cela fait maintenant 3-4 jours que je développe un petit jeu multijoueur (en temps réel) par navigateur. Il est propulsé par Phaser.js côté client et le serveur est pour l'instant développé en Ruby, avec EventMachine. Les deux communiquent grâce au protocole WebSocket, via la gem em-websockets.

Mais est-ce j'ai eu tort de choisir Ruby pour développer mon serveur ? J'ai entendu dire que ce n'était pas le meilleur des choix pour un serveur de jeu (il est relativement gourmand en ressources par rapport au C++ ou encore au Java), mais mon serveur va-t-il supporter une vingtaine de joueurs qui envoient leurs entrées clavier en continu ?

Merci d'avance

+0 -0

Vu que tu parles de jeu HTML5 et de websocket, j'ai bien envie de te répondre Node.js. Et je ne crois pas que ce n'est qu'une histoire de mode. L'avantage c'est que du fais du JS à la fois sur le client et sur le serveur.

Il y a pas mal de benchmarks sur Node.js qui tendent à le donner gagnant sur bien des choses, grâce à son mode de pensée asynchrone. IL faut toujours prendre les benchmarks avec du recul, mais c'est quand même toujours révélateur de certaines choses. Là Oû Node.js n'est clairement pas bon, c'est pour faire des gros calculs… donc si tu as beaucoup de logique de jeu côté serveur, ce n'est peut-être pas un choix judicieux.

Pour en revenir à ruby, à l'époque où j'avais voulu m'y essayer, un truc m'avait énormément bloqué: les threads sont des faux threads. Une entrée I/O, typiquement avec un socket TCP ou un fichier, ne bloquait pas seulement le thread où l'I/O était faite, mais l'ensemble du programme. En voyant ça j'avais laissé tombé direct. Mais c'était il y a au moins 5 ou 6 ans alors peut-être que ça a changé maintenant… je crois que ça devait être la version 1.8 quelque chose. Les threads totalement indépendants de la plateforme n'ont pas que des avantages et j'espère qu'ils n'ont pas persisté dans cette idée.

Autre truc chiant avec ruby que j'ai toujours l'impression de percevoir quand je fais des recherches, c'est que si tu utilises ruby, alors on suppose par la même occasion que tu utilises forcément ruby on rails. C'est presque à croire qu'en dehors de ce framework (certes populaire, très bien et avec une bonne communauté d'initiés), pour ainsi dire rien n'existe. Dans aucun autre langage on ne fait le même genre d'amalgamme (ce serait équivalent à dire que si on fait du python alors on utilise nécessairement Django; ou si on fait du PHP alors on utilise forcément Symfony; dans tous les cas c'est ridicule mais ça a l'air bien ancré pour ruby malheureusement)

De mon côté j'ai un serveur de jeu codé en Java. J'ai régulièrement 500 connectés simultanés et ça tient très bien la route. La majorité de la logique de jeu et des IA sont côté serveur mais ce n'est pas des IA très gourmandes (l'IA la plus gourmande, celle du puissance 4, est reportée sur le client).

+0 -1

Tout dépend du travail que doit faire ton serveur de jeu, mais en général, ce sont les IO qui empêchent de passer à l'échelle sur ce type d'applis et non le calcul, donc tu peux laisser C++ et Java dans leur coin si tu n'as pas envie de te les coltiner.

Ruby peut faire parfaitement l'affaire du moment qu'il supporte un truc de base : l'appel système poll, ou select (et je serais très surpris que ce ne soit pas le cas !).

À partir du moment où ton langage sait faire l'un des deux, il peut écouter sans bloquer sur un descripteur de fichier (dans ton cas une socket TCP) et donc tu peux implémenter un serveur asynchrone.

Ça résume à peu près ce que dit QuentinC juste au-dessus. Du moment que tu peux faire de l'asynchrone, tu peux gérer des dizaines de milliers de requêtes TCP par seconde sans problème. Du reste, en ce qui concerne les frameworks asynchones (pour d'éviter de perdre du temps à recoder tout le bas niveau de ton serveur), je ne sais pas trop ce qui existe en ruby.

Sinon dans ce domaine il existe deux ou trois alternatives : Node.js qui tient le sommet de la hype en ce moment, Go qui est fait exprès pour ça et offre des perfs remarquables, ou encore Python avec la bibliothèque standard asyncio, qui, depuis la sortie récente de uvloop, représente un très bon compromis entre les deux précédents, en éclatant les perfs de Node.js tout en offrant un plus haut niveau d'abstraction que Go, donc un feeling plus proche de Ruby.

+1 -0

Necros211 : j'ai regardé Crystal, le principal problème pour moi est qu'il n'est pas compatible avec les librairies Ruby. On peut tout de même utiliser le protocole WebSocket mais quelques libs vraiment pratiques pour mon serveur n'y sont pas.


EventMachine utilise des threads pour fonctionner de manière asynchrone. Donc oui, ils ont sûrement été ajoutés depuis lors.
Oui, il y a pas mal de petits calculs à faire sur mon serveur mais ça relève plus de l'addition et du Math.random qu'autre chose, je pense donc que je vais garder Ruby pour le moment. :)

Je verrai à l'avenir si j'ai besoin d'encore plus de performance.

Ah je parle bien d'asynchrone (coroutines) et non de threads. À la lecture des premières lignes de ceci, les threads de Ruby me semblent une assez peu fiables / faciles à gérer en termes de perfs, à la différence de ceux de Python (qui sont de vrais threads natifs).

En utilisant des coroutines (si ça existe en Ruby), tu t'affranchis de ces problèmes d'implémentation en prenant toi-même la main sur les interruptions (tu interromps le fil d'exécution explicitement pour te mettre en attente d'une IO), ce qui rend les serveurs beaucoup plus faciles à concevoir et à tuner.

+0 -0

Ah je parle bien d'asynchrone (coroutines) et non de threads. À la lecture des premières lignes de ceci, les threads de Ruby me semblent une assez peu fiables / faciles à gérer en termes de perfs, à la différence de ceux de Python (qui sont de vrais threads natifs).

Quand on a lu le premier paragraphe, on a tout compris. Ils ont donc gardé leurs threads portables, avec quelques avantages certes mais beaucoup d'inconvénients.

+0 -0

J'utilise en fait la gem EventMachine qui ajoute un système de programmation événementielle au langage.
N'ayant jamais vu des WebSockets manipulés autrement que par des événements (c'est des callbacks en Node.js mais je ne vois pas vraiment la différence avec un événement), je me suis naturellement orienté vers ça. La gem utilise des threads si j'ai bien compris, mais les pseudo-coroutines présentes en Ruby sont loin d'être meilleures.

Non, je pense vraiment que EventMachine est la meilleure solution en Ruby, s'il faut changer quelque chose, je pense que c'est plus le langage du coup (Golang m'a l'air intéressant).

Pour l'instant, avec un faible nombre de joueurs, le serveur consomme très peu. À voir donc ce que ça donne à plus grande échelle. :)

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte