Les sites Web modernes sont complexes et doivent souvent charger des données en arrière-plan de manière asynchrone. Le streaming JSON permet de faire cela.
Qu’est-ce que le streaming JSON ?
Le streaming JSON, ou JSONS, est une technique simple que nous utilisons pour réduire la latence de recherche, en particulier pour les utilisateurs disposant d’une connexion lente. Les utilisateurs mobiles sur des connexions HTTPS constateront la plus grande amélioration, mais tout le monde en bénéficie réellement. Avec JSONS, vous n’avez pas besoin de parseurs JSON complexes : il suffit d’envoyer du JSON délimité par des lignes. L’API de streaming de Twitter fonctionne ainsi depuis des années.
Pourquoi utiliser un flux JSON ?
Notre vérificateur de pseudos sociaux offre un exemple simple de ce fonctionnement. Nous vérifions si votre recherche est disponible sur Facebook, Twitter et Pinterest en effectuant une requête HTTP HEAD pour le nom sur chaque site. Les résultats arrivent dans un ordre aléatoire et nous voulons les afficher le plus vite possible. Nous pourrions contourner cela en envoyant trois requêtes HTTPS, mais cela signifie trois connexions TCP, trois négociations SSL, et ainsi de suite. Nous pouvons éviter cela, et probablement réutiliser une connexion HTTPS existante, en envoyant une seule requête :
https://instantdomainsearch.com/services/vanity/apple?hash=866016287
La réponse en streaming est analogue à l’encodage de transfert chunked de HTTP. Pour voir au mieux comment cela fonctionne, suivez la connexion avec curl :
curl --trace - "https://instantdomainsearch.com/services/vanity/apple?hash=866016287"
…
<= Recv data, 45 bytes (0x2d)
0000: 32 37 0d 0a 7b 22 54 79 70 65 22 3a 22 54 77 69 27..{"Type":"Twi
0010: 74 74 65 72 22 2c 22 49 73 52 65 67 69 73 74 65 tter","IsRegiste
0020: 72 65 64 22 3a 74 72 75 65 7d 0a 0d 0a red":true}...
{"Type":"Twitter","IsRegistered":true}
<= Recv data, 46 bytes (0x2e)
0000: 32 38 0d 0a 7b 22 54 79 70 65 22 3a 22 46 61 63 28..{"Type":"Fac
0010: 65 62 6f 6f 6b 22 2c 22 49 73 52 65 67 69 73 74 ebook","IsRegist
0020: 65 72 65 64 22 3a 74 72 75 65 7d 0a 0d 0a ered":true}...
{"Type":"Facebook","IsRegistered":true}
<= Recv data, 52 bytes (0x34)
0000: 32 39 0d 0a 7b 22 54 79 70 65 22 3a 22 50 69 6e 29..{"Type":"Pin
0010: 74 65 72 65 73 74 22 2c 22 49 73 52 65 67 69 73 terest","IsRegis
0020: 74 65 72 65 64 22 3a 74 72 75 65 7d 0a 0d 0a 30 tered":true}...0
0030: 0d 0a 0d 0a ....
{"Type":"Pinterest","IsRegistered":true}
== Info: Curl_http_done: called premature == 0
== Info: Connection #0 to host instantdomainsearch.com left intact
Vous rencontrerez peut-être le dogme selon lequel chaque endpoint doit renvoyer un seul objet, et un seul. Ou bien que du JSON joliment indenté peut contenir des sauts de ligne et qu’il vous faut réellement un parseur de streaming. Ignorez-les. Analyser les réponses est aussi simple que de les séparer sur les sauts de ligne. La bibliothèque jsonpipe constitue un bon point de départ pour le code de votre client.
Comment voir la différence que fait le JSON
Pour comprendre ce que cela signifie pour un utilisateur mobile, utilisez rvictl sur un Mac afin d’observer comment une véritable radio cellulaire sur un véritable réseau mobile communique avec votre serveur. Voici à quoi ressemble une connexion HTTPS sur ma connexion Verizon 3G à deux barres : la première colonne indique le temps en secondes :
0.000000 DNS 69 Standard query 0x5622 A instantdomainsearch.com
2.573090 DNS 85 Standard query response 0x5622 A instantdomainsearch.com A 130.211.25.142
Attendez, la requête DNS a pris 2,5 secondes pour être résolue ? Waouh. Le modem 3G était peut-être en mode veille. Nous pouvons enfin établir la connexion TCP :
2.573822 TCP 64 57709 → 443 [SYN] Seq=0 Win=65535 Len=0 MSS=1388 WS=64 TSval=727045548 TSecr=0 SACK_PERM=1
2.574404 TCP 60 443 → 57709 [SYN, ACK] Seq=0 Ack=1 Win=42540 Len=0 MSS=1430 SACK_PERM=1 TSval=2852312183 TSecr=727045548 WS=128
Et entamer la négociation SSL/TLS :
2.575790 TLSv1.2 285 Client Hello
3.582868 TLSv1.2 1428 [TCP Fast Retransmission] Server Hello
3.585061 TLSv1.2 127 Client Key Exchange
3.585771 TLSv1.2 58 Change Cipher Spec
3.586415 TLSv1.2 97 Encrypted Handshake Message
3.587729 TLSv1.2 103 Change Cipher Spec, Hello Request, Hello Request
Bonjour ! À partir de là, 3,5 secondes plus tard, nous envoyons et recevons enfin des données d’application chiffrées.
Le JSON réduit le nombre de paquets pour accélérer les échanges
Chaque frappe dans Instant Domain Search interroge plusieurs structures de données pour obtenir des résultats de disponibilité, des résultats de marketplace, des suggestions, etc. Nous avons constaté d’importants gains de performance lorsque nous avons cessé d’essayer d’établir autant de connexions HTTPS à chaque frappe et que nous avons plutôt renvoyé les résultats en streaming sur une connexion par requête. Vous pouvez voir que cela se traduit par beaucoup moins de paquets qui encombrent la connexion réseau de l’utilisateur. Pour mémoire, nous avons essayé d’utiliser un socket Web, mais les connexions HTTPS par requête se sont révélées être le moyen le plus fiable de fournir rapidement des résultats à nos utilisateurs.