Conditionnement efficace des données pour un réseau client-serveur

8

Langage: C ++

Ma question est la suivante: je voudrais savoir quel serait le meilleur ou au moins un bon moyen de regrouper et d'envoyer des données du client au serveur et inversement. Il y aura quelques données composant un seul paquet. Un paquet aura un "id", qui définit à quoi il sert, puis les données dans un ordre prédéterminé pour cette "action" à laquelle le paquet correspond.

Pour les systèmes moins dépendants des performances, j'enverrais simplement des chaînes, qui seraient séparées par un espace, étant elles les données de "l'action" et le premier "mot" l'identifiant du paquet et juste enchaîner si les instructions vérifient quand il y a une correspondance .

Maintenant, pour un système plus critique, ce que j'ai pensé jusqu'à présent était quelque chose comme ceci:

Créez une chaîne avec l'ID et les données du paquet et envoyez-la. Ensuite, pour décompresser, je pourrais extraire le premier entier de la chaîne, et en ayant un tableau de gestionnaires de paquets, avec des indices correspondant à l'ID de paquet qu'ils gèrent, et juste faire quelque chose comme packetHandlers [packetID] .Process (packetData).

Qu'en pensez-vous, des suggestions? grandement apprécié!

Grimshaw
la source

Réponses:

10

Tout d'abord, confirmez que vous avez réellement besoin d'un protocole sophistiqué et efficace avant de gaspiller des ressources pour le développer. N'oubliez pas que le débogage / modification de votre jeu sera plus difficile et plus long en raison de votre protocole sophistiqué. Je voudrais simplement résumer la communication réseau afin que la mise en œuvre réelle puisse être facilement échangée contre une plus efficace si nécessaire à l'avenir. Utilisez le protocole le plus simple possible jusqu'à ce que vous rencontriez des problèmes de performances. Un autre avantage de la conception ultérieure de votre protocole est que le protocole peut être optimisé pour les données réelles transportées par rapport à ce que vous prévoyez de transporter.

Après avoir confirmé que vous avez besoin d'un protocole sophistiqué, examinez les protocoles que d'autres ont passé beaucoup de temps à développer. Quelques exemples:

  • (mise à jour) Le développeur original de Protocol Buffers (v2) a développé un nouveau protocole appelé Cap'n Proto. Il explique ses décisions de conception et se compare à d'autres bibliothèques similaires qui ont récemment été publiées: Cap'n Proto, FlatBuffers et SBE .
  • Le principal goulot d'étranglement de Google est la communication réseau entre les ordinateurs, ils ont donc probablement pris en compte l'efficacité lors du développement de tampons de protocole . Gère gracieusement la compatibilité avant / arrière ( lorsque vous décidez de modifier vos structures de données). Utilisé par tous les principaux produits Google (Gmail, Recherche, etc.)
  • Apache Thrift est un protocole similaire utilisé par Facebook.
  • RakNet est une bibliothèque réseau open source spécialement conçue pour le développement de jeux.
  • ZoidCom est une autre bibliothèque de réseautage conçue pour le développement de jeux. Ce n'est pas open-source, mais vous pouvez toujours l'étudier pour des conseils de conception.

La première règle d'optimisation de programme: ne le faites pas.
La deuxième règle de l'optimisation des programmes (pour les experts seulement!): Ne le faites pas encore.

[ Michael A. Jackson ]

En d'autres termes: votre paramètre d'optimisation principal doit être: la durée de vie (années de vie par mise en œuvre du programme). [ Comment programmer des jeux indépendants. Diapositive 21. Jonathan Blow. ]

Leftium
la source
1
gentil homme de lecture! merci beaucoup pour la réponse complète, cela a certainement aidé, et je suis entièrement à vos conseils, résumez cela, ce qui est assez simple pour l'instant :)
Grimshaw
Je suis presque sûr que le cas d'utilisation de Google pour les tampons de protocole n'était pas l'efficacité au sens standard, mais pour maximiser la compatibilité entre toutes les plates-formes possibles et toutes les futures versions de données (ce qui est l'efficacité sous un autre jour). Je serai ici pour lire vos autres notes, très belle collection pour que je reprenne connaissance du sujet.
Patrick Hughes
RakNet n'est pas open source.
Gerstmann
@Gerstmann: Raknet est open source (encore une fois): github.com/OculusVR/RakNet
Leftium
0

Pourquoi utiliser deux schémas de codage différents? Utilisez simplement le second pour chaque système. Restez simple.
Pensez à utiliser la compression delta. C'est à dire envoyer une valeur complète et après cela, seules les choses qui ont changé. Après quelques itérations de jeu, renvoyez une valeur complète.
Une autre encodage que vous pourriez envisager est Base 128 Varint. Google Protobufs l'utilise. Jetez un œil à la page "Encodage" de leur guide du développeur: Encodage des tampons de protocole Pourrait économiser quelques octets.

Lurca
la source
Le premier système dont j'ai parlé n'était qu'un simple exemple d'un autre projet :) J'ai certainement apprécié l'idée de compression delta, merci mec!
Grimshaw
0

Quel pourrait être un exemple des données que vous envoyez? Je ne vois aucune raison de faire quelque chose de trop sophistiqué. Une fois que les données sont entièrement chargées dans le tampon du récepteur, inspectez le premier en intfonction de sa valeur, vous savez alors comment traiter le reste des données.

Donc , un paquet qui comporte quatre parties de données id, val1, val2et val2pourrait ressembler à ceci:

// I'm using words (one byte) so my sample data is short
00000001 00101000 00010110 00010100 

En lisant le premier octet (dont vous savez qu'il sera toujours là), vous décidez comment traiter le prochain ensemble de données. Si le premier mot (id) est que 00000001vous savez, il y a trois autres mots suivants, et c'est la fin du paquet. Pour poursuivre l'exemple, vous pourriez avoir id = 00000010et votre cahier des charges vous indique que , pour identifiant 2, vous traitez float, float, floatdans cet ordre, ce qui pourrait indiquer une position de joueur dans l' espace mondial.

Considérez-le comme l'écriture de votre propre système de fichiers binaires, vous avez une valeur d'en-tête, qui décrit le reste des données, où il se trouve (quelle position) et quel type de données pour le traiter.

Nate
la source
Compris, la seule question que je reste à poser est la suivante: est-ce que l'emballage de tous ces ints et flottants dans une chaîne standard est suffisant, ou devrais-je choisir des types de données plus légers?
Grimshaw
Comme d'autres l'ont dit, commencez par la chaîne et voyez ce qui se passe. Il y a de fortes chances que vous ayez un goulot d'étranglement ailleurs dans votre code.
Nate