Conception d’un protocole réseau pour les données / appareils mobiles en temps réel

Je suis confronté à un dilemme suivant:

Concevez un nouveau protocole réseau qui serait utilisé entre un serveur (logiciel Java) et des clients de bureau et mobiles. Les clients mobiles incluent J2ME, Android et peut-être même à l’avenir iPhone.

Le stream de données est un stream constant en temps réel avec également des pièces moins fréquentes. Les clients affichent des formes d’onde de ces données, ainsi que des données qui n’ont pas besoin d’être mises à jour instantanément. Les clients doivent également être authentifiés.

Si possible, j’aimerais éviter de créer une implémentation de protocole TCP totalement personnalisée.

De nos jours, les gens recommandent généralement de tout faire dans le style REST, ce que j’aime aussi beaucoup. Dans ce cas, j’est cependant un peu hésitant: comment implémenter un stream de données constant au-dessus de REST? Une réponse HTTP en bloc?

J’envisage également des protocoles en texte non clair (les protocoles actuels que je remplace sont des protocoles binarys). Les protocoles actuels ont des problèmes assez sérieux et doivent donc être remplacés.

Les tampons de protocole Google semblent être un très bon candidat pour gérer les détails de bas niveau, mais je ne suis pas sûr qu’il puisse être utilisé à partir d’Android. Et je suis à peu près sûr que l’implémentation de l’iPhone poserait également des problèmes.

Il y a aussi BEEP , mais je pense que c’est à peu près mort et je me demande s’il a déjà été largement utilisé.

Des idées?

Je pense qu’avant d’entrer dans la conception de protocoles, vous devez vous occuper des problèmes suivants avec beaucoup d’attention:

  • Presque tous les protocoles sauf HTTP sont filtrés par des pare-feu de nos jours. Même de nombreux types de contenu et ports (sauf 80) peuvent être filtrés par les fournisseurs de services, en particulier dans les services de données mobiles. Par conséquent, assurez-vous de ne pas avoir de problème de pare-feu dans votre réseau cible avant de choisir d’utiliser ou de concevoir un protocole.
  • La taille et la vitesse comptent. Essayez d’utiliser des protocoles efficaces à la fois en taille de message de transport et en vitesse de codage / décodage (sérialisation / désérialisation). Google Protocol Buffers fournit une solution fiable à ce problème.
  • Les connexions sont toujours déconnectées. Vous ne pouvez jamais compter sur une connexion pour restr ouverte longtemps à cause des délais d’attente NAT (15 minutes par défaut), des délais de protocole (30 minutes pour TCP) et de nombreux problèmes de réseau existants. Donc, ne préférez pas un protocole à l’autre simplement parce que la connexion rest ouverte (elle peut essayer, mais ne réussit jamais). L’envoi de pulsations est un bon moyen de résoudre le problème de délai d’attente, mais les déconnexions réseau restnt inévitables.
  • Le débit compte. Par débit, j’entends le nombre de messages traités sur une période donnée (par exemple 1 seconde). L’utilisation de protocoles asynchrones qui déconnectent un client après réception de son message consortingbue réellement à augmenter le débit. Bien que ne vous fiez pas à la connexion au client depuis le serveur pour pousser le résultat, de nombreux clients sont derrière des NAT et des pare-feu, ce qui évite une connexion directe de l’extérieur. Essayez de garder la connexion ouverte ou interrogez le serveur pour obtenir le résultat. Éviter l’état dans une conversation est également l’autre méthode qui permet d’augmenter le débit des applications à mesure que le nombre de clients augmente.
  • Il n’y a pas de temps réel dans les réseaux étendus existants. Ne faites pas confiance à ceux qui disent avoir implémenté un protocole en temps réel basé sur les protocoles de réseau étendu existants. Vous ne pouvez jamais implémenter un protocole en temps réel par-dessus des protocoles en temps non réel. Vous pouvez simplement faire de votre mieux et prier pour que le réseau aille vite. Cela signifie: ne vous arrêtez pas, faites de votre mieux.
  • IO non bloquant. NIO (Non-blocking IO) est la tendance actuelle, utilisée efficacement dans la programmation réseau. Il permet un grand nombre de connexions avec une utilisation moindre de la mémoire et un nombre limité de threads. Java 5 a un support natif pour NIO qui est très primitif. De nombreux frameworks, tels que Apache MINA et Netty , ont été mis en œuvre sur Java NIO pour rendre la programmation non bloquante plus facile et plus robuste. Je les recommande fortement.

Vous pouvez regarder Kryo et / ou KryoNet , qui sont basés sur NIO et Java et fonctionnent sur le bureau et sur Android. Il faudrait cependant écrire du côté de l’iPhone, ce qui serait plutôt délicat. Kryo surpasse les tampons de protocole de Google en taille sérialisée ( références ici ) et facilité d’utilisation (aucun schéma de type .proto ne doit être écrit, avec Kryo les définitions de classe Java sont le schéma).

En ce qui concerne NIO, vous pouvez consulter NPTL . L’ancien redevient neuf.

Vous voudrez peut-être examiner le protocole de transport en temps réel (RTP) , qui peut ne pas être directement utile (et / ou peut-être excessif), mais sa conception vous donnerait de bonnes idées pour travailler. Et vous pourrez peut-être l’utiliser.

Ce n’est pas une solution élégante, mais vous pouvez le faire sur http directe, en ne définissant pas le champ content-length sur la réponse http et en ne fermant jamais le stream de sortie. Continuez simplement à envoyer des données.

Vous pouvez également définir une très grande longueur de contenu et renvoyer des données du serveur en temps réel jusqu’à ce que le serveur envoie ce montant. Le client peut alors choisir de faire une nouvelle demande ou non.

Malheureusement, je n’ai trouvé aucun lien utile pour ces idées, mais j’espère que vous aurez les idées.

Le véritable avantage de ces idées est qu’elles survolent http, ce qui élimine le problème du pare-feu, et vous pouvez implémenter votre application en tant qu’application Web avec une servlet.

Juste mes 2 cents;)