Bonjour,
Je suis étudiant en licence pro et je dois actuellement développer un jeu de poker en ligne avec Java EE.
Le principe est simple :
- Un joueur se connecte et attend que 3 autres joueurs le rejoignent.
- Quand tous les joueurs sont la, la partie peut commencer.
Pour que les joueurs puissent suivre l'évolution de la partie, j'actualise le navigateur de chaque joueur avec des requêtes ajax (qui demandent la page a une servlet) .
Pour que chaque client n'envoie pas une requête par seconde au serveur, j'ai mis au point un système basé sur des sémaphores dans les servlets appelées, pour que la requête soit bloquée lorsque il n'y a rien a mettre a jour.
Ainsi, a chaque fois qu'une action a lieu (par exemple un joueur décide de relancer), on autorise les joueurs a se mettre a jour en débloquant la sémaphore et donc les requêtes ajax en attente.
Le problème que je rencontre me donne du fil a retordre depuis deux semaines: Quand une requete ajax est bloquée (et donc en attente d'une nouvelle action), c'est tout le serveur qui est bloqué (alors qu'un serveur Java EE (Tomcat chez moi) est sensé être multi-thread non ? ). Et donc la page est continuellement en chargement dans le navigateur des joueurs.
Quelqu'un aurait il une idée pour résoudre ce problème ?
En gros ce qui se passe quand une requete ajax est envoyé a la servlet :
Code de la servlet
Code java : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 Joueur j = (Joueur) request.getSession().getAttribute("joueur"); String pseudo; if (j == null) { pseudo = "none"; this.getServletContext().getRequestDispatcher("/WEB-INF/dynamic/gameStatus/isAGameLaunched.jsp").forward(request, response); } else { pseudo = j.getPseudo(); MultiSemaphore sem = this.getWaitSem(); Semaphore s = sem.getSemaphore(pseudo); // On récupere le sémaphore du joueur try { s.acquire(1); // On lui prend un jeton. Si il n'y en a pas, on attend qu'il y en aie (action d'un joueur). C'est ce qui bloque tout le serveur. if (request.getParameter("query").equals("isReady")) { if (isTousLesJoueursPresents()) { this.getServletContext().getRequestDispatcher("/WEB-INF/dynamic/gameStatus/isAGameLaunched.jsp").forward(request, response); } } else { this.getServletContext().getRequestDispatcher("/WEB-INF/dynamic/gameStatus/isAGameLaunched.jsp").forward(request, response); } } catch (InterruptedException ex) { Logger.getLogger(index.class.getName()).log(Level.SEVERE, null, ex); } }
Partager