Moderne websites zijn complex en moeten gegevens vaak asynchroon op de achtergrond laden. JSON-streaming is een manier om dat mogelijk te maken.
Wat is JSON-streaming?
JSON-streaming, of JSONS, is een eenvoudige techniek waarmee we de zoekvertraging voor gebruikers verkleinen, vooral bij een trage verbinding. Mobiele gebruikers met HTTPS-verbindingen merken de grootste verbetering, maar iedereen heeft er baat bij. Voor JSONS heb je geen ingewikkelde JSON-parsers nodig: verstuur gewoon JSON die per regel is gescheiden. De streaming-API van Twitter werkt al jaren zo.
Waarom je een JSON-stream zou moeten gebruiken
Onze controletool voor gebruikersnamen op sociale media laat eenvoudig zien hoe dit werkt. We controleren of je zoekterm beschikbaar is op Facebook, Twitter en Pinterest door op elke website een HTTP HEAD-verzoek voor de naam uit te voeren. De resultaten komen in willekeurige volgorde binnen en we willen ze zo snel mogelijk tonen. Dat zouden we kunnen oplossen met drie HTTPS-verzoeken, maar dat betekent drie TCP-verbindingen, drie SSL-handshakes enzovoort. We kunnen dit vermijden, en waarschijnlijk een bestaande HTTPS-verbinding hergebruiken, door slechts één verzoek te versturen:
https://instantdomainsearch.com/services/vanity/apple?hash=866016287
Het streamingantwoord is vergelijkbaar met, en afhankelijk van, HTTP chunked transfer encoding. De beste manier om te zien hoe dit werkt, is de verbinding met curl te volgen:
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
Misschien kom je de technische dogma’s tegen dat elk eindpunt precies één object moet teruggeven. Of dat netjes opgemaakte JSON regeleinden kan bevatten en je dus eigenlijk een streamingparser nodig hebt. Negeer die. Antwoorden verwerken is zo eenvoudig als splitsen op regeleinden. De bibliotheek jsonpipe is een goed beginpunt voor je clientcode.
Zo zie je het verschil dat JSON maakt
Een goede manier om te zien wat dit voor een mobiele gebruiker betekent, is rvictl op een Mac gebruiken. Daarmee zie je hoe een echte mobiele radio via een echt mobiel netwerk met je server communiceert. Eén HTTPS-verbinding op mijn Verizon 3G-verbinding met twee streepjes bereik ziet er zo uit. De eerste kolom toont de tijd in seconden:
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
Wacht, duurde het beantwoorden van de DNS-vraag 2,5 seconden? Wauw. Misschien stond de 3G-modem in slaapstand. Eindelijk kunnen we de TCP-verbinding opzetten:
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
En beginnen aan de SSL/TLS-uitwisseling:
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
Hallo! Vanaf dit punt, 3,5 seconden later, versturen en ontvangen we eindelijk versleutelde toepassingsgegevens.
JSON vermindert pakketten en verhoogt de snelheid
Elke toetsaanslag op Instant Domain Search bevraagt meerdere gegevensstructuren voor beschikbaarheidsresultaten, marktplaatsresultaten, suggesties enzovoort. We zagen enorme prestatieverbeteringen voor gebruikers toen we niet meer bij elke toetsaanslag zoveel HTTPS-verbindingen probeerden op te zetten, maar de resultaten via één verbinding per zoekopdracht terugstroomden. Je ziet hoe dit veel minder pakketten oplevert die de netwerkverbinding van de gebruiker belasten. Voor de volledigheid: we probeerden ook een WebSocket, maar ontdekten dat HTTPS-verbindingen per zoekopdracht de betrouwbaarste manier waren om onze gebruikers snel resultaten te leveren.