Langage : C++ avec colle logique Lua.
Le code a été testé pour être compilé et exécuté sur Ubuntu x86, Ubuntu x86_64 et Gentoo x86_64 étant donné que la version appropriée de LuaJIT est utilisée. Modifications de libjansson pour supprimer le formatage forcé des flottants avec .0 après que les nombres entiers aient été effectués afin de prendre correctement en charge les "entiers" et d'avoir toujours la conversion automatique à partir de Lua, qui ne prend en charge que les doubles.
Il compile également sur Ubuntu 12.04 LTS x86_64, étant donné que libjansson et google-glog sont construits manuellement.
LuaJIT
Libev
evhttpclient
google-glog
google-perftools (tcmalloc) - Facultatif avec des modifications mineures des sources et du makefile
Libjansson
embauché
libicu - voir le gestionnaire de paquets local
curl - voir le gestionnaire de paquets local
boost - Facultatif si vous remplacez les pointeurs intrusifs par quelque chose qui vous est propre.
Des modifications de src/Makefile pour refléter vos dossiers d'installation seront probablement nécessaires. Un système de construction plus robuste est le bienvenu, mais n'était pas requis au moment de la rédaction du projet. (CMaire ?)
J'ai (@zwagoth) appris quelque chose ici : faites toujours des commentaires au moment de la rédaction. Pour compenser cela, je documenterai la structure de base du programme pour faciliter la compréhension.
Toutes mes excuses pour le désordre d'une base de code. C'était également l'un de mes premiers projets C++, quelle que soit leur ampleur et leur complexité.
Contient presque toute la logique de base pour la gestion des messages de protocole, des messages RTB et divers rappels d'événements de base tels que la connexion et la déconnexion.
Le fichier contient des tableaux de fonctions anonymes nommées d'après les événements qu'elles gèrent. Ce fichier ne doit stocker aucun état et est considéré uniquement comme une zone de stockage logique. La conception de base de ce fichier est de permettre une logique de collage sans forcer Lua à faire de gros travaux et en minimisant la quantité de données transférées dans et hors de Lua au prix de davantage d'appels de fonctions en C++.
Quatre tables sont injectées dans l'espace de noms de fichier global avec des noms courts pour faciliter la saisie :
u
: fonctions connexion/caractère (utilisateur)
s
: fonctions serveur/état global
c
: fonctions d'état du canal
const
: identifiants d'erreur et valeurs constantes
Les fonctions de rappel de protocole acceptent deux paramètres, la connexion à laquelle la commande est associée et une copie de table des arguments json fournis.
Les connexions sont des nombres opaques et ne doivent en aucun cas être modifiées. Changer la valeur d’une connexion n’est pas sûr. Vous êtes prévenu.
Un fichier Lua de variables de configuration utilisées lors du démarrage et du fonctionnement du démon de discussion.
Un serveur de stratégie flash minimaliste. Si vous avez besoin de prendre en charge Flash, c'est ce que vous exécutez. Personnalisez la stratégie intégrée selon vos besoins.
Point d’entrée du programme. Traite de l'initialisation des threads d'arrière-plan et du curl.
Fait beaucoup trop de choses. Le flux de code commence à Server::run()
.
Le flux de connexion est le suivant :
listenCallback handshakeCallback connectionWriteCallback connectionReadCallback connectionwriteCallback
listenCallback
configure des gestionnaires d'événements par connexion et transmet le flux dans...
handshakeCallback
, qui gère les lectures pour les poignées de main Websocket.
connectionWriteCallback
gère le moment où une connexion est prête à être écrite et est activé lorsque des éléments sont dans la file d'attente pour être écrits sur la connexion. Gère la mise en mémoire tampon.
connectionReadCallback
gère tous les événements de lecture lorsque la phase de prise de contact est terminée. Toute l'analyse du protocole s'effectue ici et les commandes sont distribuées et exécutées depuis cette fonction.
pingCallback
gère l'envoi d'événements ping aux clients. Si le protocole est modifié, cela devrait être l’une des premières choses à faire.
connectionTimerCallback
est déclenché périodiquement et vérifie si la connexion est morte et la nettoie.
runLuaEvent
est une nouvelle magie. C'est aussi là que la magie opère pour chaque commande. C'est là que chaque commande passe du code C++ au code Lua. Gère tous les états de Lua et le rappel pour s'assurer que Lua ne soit pas pris dans une boucle infinie. Gère les erreurs d’impression depuis Lua.
Ce fichier stocke toutes les données d'état liées aux chaînes, aux connexions, aux interdictions et à la modération.
Les connexions sont divisées entre identifiées et non identifiées, car les noms des personnages ne sont pas connus tant que le serveur de connexion n'a pas validé leur existence et les a exclus du pool de caractères pouvant être recherchés par leur nom.
Gère la sauvegarde et la restauration de l’état sur le disque.
S'exécute comme un thread d'arrière-plan qui traite les demandes de connexion et les réponses et les renvoie au thread principal.
Système de connexion sérialisé, utilise une file d'attente de connexion globale. Cela pourrait être un peu amélioré.
La conversion en curl_multi serait bien, mais implique une interaction amusante avec libev ou de nombreux sondages à l'aveugle. Les files d'attente doivent être verrouillées avant d'y accéder, en raison du threading.
Classe de canal de base, conserve les données d'état sur un canal pendant toute sa durée de vie. Toutes les actions de bas niveau liées aux canaux se produisent dans ce fichier via des hooks dans Lua. Généralement enveloppé dans un pointeur intrusif pour gérer la durée de vie de l’instance.
C'est là que se produit la sérialisation et la désérialisation des canaux à partir de JSON.
Gère tous les états de connexion réseau et de débogage Lua.
Maintient les listes de kinks, le statut, le message de statut et le sexe.
Maintient la liste des ignorés et des amis.
Poignées par manette de connexion.
C'est là que se produit la mise en mémoire tampon des données de sortie.
Généralement transmis à l’aide de pointeurs intrusifs pour gérer la durée de vie de l’instance.
Maintient une liste interne des chaînes qui ont été rejointes. Cela doit être synchronisé avec la liste réelle des utilisateurs du canal.
Ce fichier est réservé aux quelques fonctions qui nécessitaient une vitesse brute plutôt que d'être personnalisables. Gère la commande de connexion ( IDN
). Gère la commande de débogage ( ZZZ
). Gère la commande de recherche ( FKS
).
Toutes les commandes du wrapper Lua qui relèvent de la catégorie s
dans les fichiers Lua.
Toutes les commandes du wrapper Lua qui relèvent de la catégorie u
dans les fichiers Lua.
Toutes les commandes du wrapper Lua qui relèvent de la catégorie c
dans les fichiers Lua.
Toutes les valeurs du wrapper Lua qui relèvent de la catégorie const
dans les fichiers Lua.
Messages d'erreur et définitions.
Utilisez les macros définies pour la vérification des erreurs et du type ! C'est le seul moyen d'éviter un plantage si le type incorrect est transmis de manière inattendue sous forme de données légères dans une fonction.
Assurez-vous que votre pile Lua est équilibrée. J'ai essayé de m'assurer que cela soit vrai, mais les erreurs sont faciles à commettre.
Évitez de renvoyer les tables au code Lua, elles sont coûteuses à construire et ont souvent une courte période d'utilisation. Faites preuve de jugement pour équilibrer le coût des appels de fonction et le coût de création des tables.
Évitez de passer inutilement des chaînes dans Lua. Cela peut être coûteux en raison des copies de mémoire.
Abusez du fait que Lua accepte plusieurs valeurs de retour en tant que fonctionnalité native. Voir ci-dessus deux notes.
Gère le thread redis push uniquement. Est un petit wrapper autour des commandes Redis et de leurs valeurs de retour.
Utilise une file d'attente d'entrée pour recevoir des commandes. Les commandes sont exécutées de manière périodique et n'ont aucune garantie de fiabilité. Peut être désactivé et ignore les entrées lorsqu'il est désactivé.
gdb fonctionne bien pour déboguer cette application. La désactivation de tcmalloc et de la section JIT de LuaJIT devrait grandement aider au débogage des plantages (tcmalloc peut masquer une corruption mineure du tas).
Les outils de profilage de mémoire dans tcmalloc sont plutôt sympas. Reportez-vous à la documentation de tcmalloc pour plus d'informations sur son utilisation.