[Boost::Asio] Plusieurs questions
Bonjour à tous,
Voilà, j'ai quelques questions à poser, travaillant actuellement sur une architecture client/serveur pour un MMORPG, j'utilise tout naturellement boost::asio (je me penche actuellement sur un TaskManager ou ThreadPoolManager).
Même si vous ne connaissez pas la réponse, vos idées/suggestions me seront utiles :)
1ère question :
Le premier schéma utilisé pour gérer tous ces utilisateurs était le suivant :
chaque session utilisateur est en fait un thread, qui est lancé par la ThreaPool à la connexion de l'utilisateur. Chaque session écoute donc en boucle (asio::read()) sur son socket en attente de recevoir un packet.
On reçoit dans un buffer taille 1 de multiple fois jusqu'à avoir complètement reconstitué le packet puis on l'analyse, et on éxécute la fonction associée, bref.
Le point faible survient évidemment lorsque le nombre d'utilisateur augmente : on augmente le nombre de thread à gérer, ce qui doit être plutôt lourd au final.
Voilà ce que j'aimerais donc faire pour être plus efficace :
La threadpool est optimisée pour avoir un nombre de thread limité :
Le thread de login s'occupe de la connexion (plutôt qu'une fonction async),
Le thread de selection reçoit l'ensemble des packets venant des clients, analyse et place chaque tâche dans une queue
Les threads "workers" vont sans arrêt prendre les tâches venant de la queue et les exécuter
Et c'est là que je bloque :
J'ai d'abord pensé stocker toutes les sockets clientes dans un vector (par exemple), puis boucler dessus et faire un certain nombre de tour de boucle puis passer au socket suivant, etc ...
Cependant malgré la vitesse d'exécution du principe, il y aura un temps d'attente en cas de nombre élevé de client. Procédé à exclure.
Ensuite, j'ai pensé effectivement continuer de boucler sur les sockets, mais en lançant une opération de réception async pour chacun d'entre eux.
Une fois la réception terminée, le callback analyse le packet et place la tâche aux bon soins des workers.
Mais question : est-ce que ça ne reviendrait pas à faire un équivalent du premier schéma que j'ai évoqué plus haut ? Avec 1 000 clients, on aurait 1000 réception asynchrone sans arrêt, si tenté que ceci soit réalisable
Justement : Est-ce que je me plante complètement et qu'une meilleure technique existe pour gérer de multiples clients en même temps ?
2ème question :
Une IP PC est-elle stable (est-elle sujète à changement autrement dit) ?
Peut-on récupérer l'IP PC avec boost::asio ? (Pour un système de banIP efficace ...)
3ème question :
Comment implémenter un programmateur ? C'est à dire qu'il me faudrait un thread à part pour les tâches qui ne doivent être exécutée qu'à un certain horaire, ou tout les x temps ...
J'ai pensé à un tableau <pair <"délai_avant_exécution", tâche> > au lieu d'une queue. Les workers regardent si une tâche peut-êre exécutée, regarde son timer, si = 0 exécute sinon on parcourt encore le tableau pour trouver une tâche exécutable.
Je pense que ça peut marcher, mais qu'en est-il si je veux scripter un évènement se déroulant tous les jours à 18h00 par exemple ? ça veut dire que la tâche resterait 24h dans le tableau en attente, ce qui n'est pas vraiment
optimisé question mémoire (d'autant que si cette tâche est seule, les workers vont passer dessus sans arrêt en attendant de pouvoir l'exécuter).
Cela dit je n'ai pas d'autre idée pour le moment. Des pistes ? :) (Et merci de cette lecture.)