Tetris on the cloud !
Il y a quelque temps (un peu plus de 2 ans 1/2), je testais WPF, WCF, WF et à cette occasion j’avais réalisé un jeu, une forme de “Tetris” mais multi-joueurs

Celui-ci était réalisé avec le framework 3.0.
Un framework et un servicepack plus tard j’ai donc décidé de le faire évoluer, et d’utiliser Windows Azure.
Architecture d’origine
Chaque joueur pouvant être “serveur”, toutes connexions entre les joueurs passe par le serveur.
Le serveur doit être connu de tout les participants. Le serveur est un service WCF basé sur le protocole “net.p2p”. J’ai pour cela dérivé la classe “System.ServiceModel.PeerResolver”.
Inconvénients
- Le joueur serveur reçoit toute les connexions, si il “tombe” le jeu est terminé pour l’ensemble des joueurs
- autre inconvénient majeur de cette solution est l’ouverture d’un port sur toute les machines.
- Le joueur serveur est aussi avantagé, sa connexion avec le “serveur” est locale.
- Cette architecture était plutôt orientée LAN
Le but au départ était de montrer un exemple utilisant les nouvelles briques du framework 3.0.
Ce qu’apporte Windows Azure et le ServiceBus
Pour ce jeu, j’ai tout simplement remplacer toute la partie qui gère le p2p entre les joueurs, c’est le rôle de la plateforme Azure. Si vous ne connaissez pas cette plateforme vous trouverez pas mal d’informations ici.
Le service utilisé dans ce jeu est le ServiceBus, et plus particulièrement la publication/souscription en multicast.
Tous les participants sont connectés sur un même point central (défini par une uri), et ainsi peuvent envoyer/recevoir sans avoir besoin de se connaitre mutuellement.
ainsi la nouvelle architecture est :
ceci est l’état du système lors d’une phase de jeu. Mais que ce passe-t-il avant….au commencement du jeu…
- Le joueur qui désire être serveur, envoi un message “SendRequest” avec l’uri pour répondre (ici : sb://…/Guid/Acceptor)
- les joueurs souhaitant participer se connectent au service d’acceptation pour obtenir une autre Uri, cette fois celle du service multicast pour la nouvelle partie. celle-ci est générée dynamiquement à chaque nouvelle partie.
- les joueurs ayant accepter l’invitation du serveur se retrouvent connectés ensemble sur un point qu’il sont seuls à connaitre.
ainsi plusieurs parties peuvent avoir lieu au sein de la même “solution“ Windows Azure
Les différentes interfaces des différents services
La gestion de la connexion (service représenté en orange ci-dessus), ce service permet au joueurs de se voir mutuellement
[ServiceContract(Namespace = Constants.ContractNamespace)]
public interface IPeerConnexionService
{
#region connection managment
/// <summary>
/// used to join, others player should respond with hello
/// </summary>
[OperationContract(IsOneWay = true)]
void Join(PeerPlayer player);
/// <summary>
/// used to leave the room
/// </summary>
[OperationContract(IsOneWay = true)]
void Leave(PeerPlayer player);
/// <summary>
/// the new player receive one "Hello" from all other players
/// </summary>
[OperationContract(IsOneWay = true)]
void Hello(PeerPlayer player);
/// <summary>
/// used to send a ping to a specific player
/// </summary>
[OperationContract(IsOneWay = true)]
void Ping(PeerPlayer from, PeerPlayer to);
/// <summary>
/// used to respond from ping
/// </summary>
/// <param name="from"></param>
/// <param name="to"></param>
[OperationContract(IsOneWay = true)]
void Pong(PeerPlayer from, PeerPlayer to);
/// <summary>
///
/// </summary>
/// <param name="player"></param>
/// <param name="acceptor">uri of the acceptor service</param>
[OperationContract(IsOneWay = true)]
void SendGameRequest(PeerPlayer player, Uri acceptor);
#endregion
}
Le service que chaque joueur publie pour accepter les autres joueur dans son espace de jeu. ce service à la particularité d’être un service “wcf” standard, contrairement aux autres qui sont “multicast”
[ServiceContract(Namespace = Constants.ContractNamespace)]
public interface IAcceptorService
{
[OperationContract]
Uri IWouldLikeToplay(PeerPlayer player);
}
service utiliser pendant la phase de jeu (en vert sur le schéma ci-dessus)
[ServiceContract(Namespace = Constants.ContractNamespace)]
public interface ITetrisGameService
{
[OperationContract(IsOneWay = true)]
void SendBoard(Guid idplayer, byte[] board, int lengthDimension0, int lengthDimension1);
[OperationContract(IsOneWay = true)]
void SetTimerInterval(Guid idplayer, double newValue);
[OperationContract(IsOneWay = true)]
void GameOver(Guid idplayer);
[OperationContract(IsOneWay = true)]
void SendOption(Guid from, Guid to, byte option);
[OperationContract(IsOneWay = true)]
void SendScore(Guid idplayer, int score);
[OperationContract(IsOneWay = true)]
void HideBoard(Guid idplayer, bool value);
[OperationContract(IsOneWay = true)]
void GameStarting(Guid idCoordinator, int nbPlayer);
[OperationContract(IsOneWay = true)]
void PlayerReady(Guid idplayer);
[OperationContract(IsOneWay = true)]
void ImIn(Guid idplayer);
}
Premières impressions
- extrêmement simple de publier un service mondialement ! ;-)
- c’est du WCF, donc la configuration est identique à ce que l’on connais déjà
- la publication des services sur le cloud reste assez lente (plusieurs secondes par service)
- il ne faut pas oublier que le framework Windows Azure est en CTP
- par contre ensuite (dans le cadre du tetris) une fois la connexion établie, les échanges sont fluides.
- vous le remarquerez en cliquant sur “connect to mesh” dans le menu “game”
Utiliser ce jeu
Téléchargez l’installation depuis codeplex : http://geniustetris.codeplex.com/
une fois installer il faut modifier le fichier de configuration de l’application “geniustetris.exe.config”, plus précisément les “credentials” pour se connecter à windows azure
<behaviors>
<endpointBehaviors>
<behavior name="password">
<transportClientEndpointBehavior credentialType="UserNamePassword">
<clientCredentials>
<userNamePassword userName="GeniusTetris" password="****" />
</clientCredentials>
</transportClientEndpointBehavior>
</behavior>
</endpointBehaviors>
</behaviors>
Remplacer “GeniusTetris” par le nom votre solution Windows Azure, et le mot de passe par le votre. n’oubliez pas de modifier dans le jeu les options “réseaux” et de fournir le nom de la solution à utiliser.
il est possible d’utiliser d’autres moyens d’authentification comme “CardSpace”, cela fonctionne aussi.
vous voulez jouer ? alors rendez vous sur http://geniustetris.codeplex.com/
bon amusement !
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :