- Ilga aptauja simulē servera nosūtīšanu, izmantojot HTTP, taču cieš no galvenes papildu slodzes, taimauta īpatnībām un resursu ierobežojumiem.
- Starpniekserveri, pārlūkprogrammas savienojuma ierobežojumi un kešatmiņa var nemanāmi pārtraukt vai pasliktināt garu aptauju darbību plašā mērogā.
- Protokoli, piemēram, Bayeux un BOSH, balstās uz garo aptauju, lai piedāvātu divvirzienu ziņojumapmaiņu, bieži vien līdztekus straumēšanai.
- Optimizēti taimauti, pakešošana, saspiešana un rūpīga atkārtotas mēģināšanas loģika ir būtiska, lai JavaScript ilgās aptaujas būtu stabilas.
Gara aptauja JavaScript valodā izskatās maldinoši vienkārša: turiet HTTP pieprasījumu atvērtu, līdz serverim ir ko teikt, atgrieziet datus un nekavējoties atveriet jaunu pieprasījumu. No malas tas šķiet gandrīz kā reāllaika saziņa, tāpēc nav pārsteigums, ka tērzēšanas lietotnes, informācijas paneļi, spēles un paziņojumu sistēmas uz to ir paļāvušās gadiem ilgi. Taču zem pārsega ir smalkas veiktspējas, mērogojamības un uzticamības nepilnības, kas izpaužas, tiklīdz jūsu lietotnē ir vairāk nekā tikai nedaudz lietotāju.
Lai izprastu īstās aptaujas problēmas JavaScript valodā, ir jāiet tālāk par pamata aprakstu “klients nosūta pieprasījumu, serveris gaida, serveris atbild” un jāaplūko HTTP semantika, pārlūkprogrammas ierobežojumi, starpniekserveri, taimauti un alternatīvas, piemēram, WebSockets, HTTP straumēšana un servera nosūtītie notikumi. Šajā rokasgrāmatā mēs padziļināti aplūkosim, kā darbojas īsā aptauja, kādas problēmas ir identificējuši IETF un lielākie pārdevēji, un kā izlemt, kad to izmantot, kad to optimizēt un kad pilnībā aizstāt.
Kas īsti ir garā aptauja JavaScript valodā

Vienkārši sakot, garā aptauja ir modelis, kas izveidots, izmantojot parasto HTTP protokolu, kur pārlūkprogramma nosūta pieprasījumu, un serveris apzināti aizkavē atbildi, līdz ir pieejami jauni dati vai beidzas taimauts. Tiklīdz pārlūkprogramma saņem atbildi, tā apstrādā datus un nekavējoties nosūta citu pieprasījumu, atstājot savienojumu "gandrīz vienmēr" gaidīšanas režīmā.
Šī plūsma ļoti atšķiras no klasiskās īsās aptaujas, kur klients fiksētā intervālā uzdod serverim jautājumu: "Vai ir kaut kas jauns?" neatkarīgi no tā, vai ir atjauninājumi. Izmantojot garo aptauju, serveris neaktivitātes periodos tur pieprasījumu atvērtu, tāpēc klientam nav atkārtoti jāsūta tukšas aptaujas, ja nekas nav mainījies.
Tipisks JavaScript garš aptaujas cikls izskatās kā rekursīva subscribe funkcija, kas izsauc fetch (vai XMLHttpRequest), gaida atbildi, apstrādā vērtumu un pēc tam atkal izsauc sevi. Ja tīkla savienojums pārtrūkst vai rodas kļūda, kods nekavējoties vai pēc nelielas aizkaves mēģina vēlreiz, cenšoties pēc iespējas ilgāk uzturēt šo gaidošo savienojumu dzīvu.
Šī pieeja īpaši labi darbojas, ja ziņojumi ir relatīvi reti, jo savienojuma dīkstāves laiks nerada tīkla trafiku vai procesora slodzi, kas pārsniedz ligzdas atvēršanas uzturēšanas izmaksas. Lietotājs saņem gandrīz tūlītējus atjauninājumus, savukārt serveris netiek pastāvīgi bombardēts ar aptaujas pārbaudēm.
Tomēr, tiklīdz notikumi kļūst bieži, katrs notikums mēdz izraisīt veselu HTTP atbildes ciklu — statusa rindu, galvenes, autentifikāciju, pamattekstu —, tāpēc ziņojuma izmaksas var eksplodēt, un datplūsmas modelis sāk izskatīties kā zāģzobains pieprasījumu/atbilžu pieaugums. Tieši tur reālās pasaules lietotnēs sāk parādīties problēmas ar mērogošanu un papildu izmaksām.
Īsa aptauja salīdzinājumā ar garu aptaujas un straumēšanu

Lai patiesi izprastu problēmu jomu, ir lietderīgi pretstatīt garo aptaujāšanu gan ar īso aptaujāšanu, gan HTTP straumēšanu, jo visi trīs ir veidi, kā viltot “piegādi” pār principiāli pieprasījuma/atbildes protokolu, piemēram, HTTP.
Īsa aptauja ir naivā variācija: klients periodiski nosūta HTTP pieprasījumus (piemēram, ik pēc 5–10 sekundēm), un serveris nekavējoties atbild ar visiem ziņojumiem, kas saņemti kopš pēdējās aptaujas. Ja nekas nav pieejams, serveris joprojām atbild, bieži vien ar tukšu vērtumu, un klients vienkārši gaida līdz nākamajam intervālam.
Šim modelim ir divi acīmredzami trūkumi: ziņojumu latentums var būt tikpat liels kā aptaujas intervāls, un serverim ir jāapstrādā atkārtoti pieprasījumi pat tad, ja nav jaunu datu. Mazām vai mazas datplūsmas sistēmām tas varētu būt pieņemami, taču lielā mērogā tas izšķērdē centrālā procesora ciklus, tīkla joslas platumu un var radīt ievērojamas kavēšanās lietotājiem.
Ilga aptauja uzlabo šo iespēju, ļaujot serverim "turēt atvērtu" katru pieprasījumu, līdz notiek kaut kas interesants — piegādājams notikums vai taimauta slieksnis. Jaunu ziņojumu latentums tagad ir tuvu vienam tīkla ziņojumam turp un atpakaļ, un tukšas atbildes rodas daudz retāk, samazinot nelietderīgu datplūsmu.
HTTP straumēšana iet soli tālāk, nekad neaizverot atbildi: serveris nosūta vienu HTTP atbildi un pēc tam straumē vairākus datu fragmentus pa to pašu savienojumu, atdalītus ar kādu kadrēšanu lietojumprogrammas līmenī. Klients nolasa straumi pakāpeniski, nevis gaida, kamēr visa atbilde ir pabeigta.
HTTP/1.1 standartā tas parasti tiek ieviests, izmantojot fragmentētu pārsūtīšanas kodējumu, kur serveris iestata Transfer-Encoding: fragmentēts un pēc tam nosūta katru datu vienību kā atsevišķu fragmentu ar savu garuma galveni. HTTP/1.0 stila iestatījumos straumēšanu var panākt arī, izlaižot Content-Length un izmantojot connection close kā straumes beigu marķieri.
Būtiskākā atšķirība ir tā, ka garā aptauja aizver atbildi pēc katra ziņojuma, piespiežot veikt jaunu pieprasījumu nākamajam notikumam, savukārt straumēšana saglabā to pašu atbildi un nosūta ziņojumus, tiklīdz tie parādās. Tam ir būtiska ietekme uz latentumu, atmiņas izmantošanu, starpniekserveriem un to, kā jūs veidojat ziņojumus lietojumprogrammas slānī.
Kā darbojas HTTP garā aptauja zem pārsega
No HTTP protokola viedokļa garā aptauja neievieš nekādas jaunas metodes vai statusa kodus; tā tikai paplašina ierasto pieprasījuma semantiku, kas gaida atbildi. IETF "divvirzienu HTTP" analīze skaidri parāda, ka garā aptauja joprojām ir derīga HTTP 1.0/1.1, taču tuvina modeļa robežas.
Garas aptaujas mijiedarbības pamata dzīves cikls izskatās šādi: klients nosūta sākotnējo pieprasījumu un veic pauzi, serveris atliek atbildi, līdz notiek notikums, statusa maiņa vai taimauts, pēc tam serveris atgriež pilnu HTTP atbildi (bieži vien 200 OK) ar notikuma datiem, un visbeidzot klients ātri izdod jaunu pieprasījumu.
Šo modeli var izmantot gan pastāvīgos, gan nepastāvīgos HTTP savienojumos; ar pastāvīgiem savienojumiem jūs izvairāties no atkārtotu TCP aptauju radītajām papildu izmaksām, atkārtoti izmantojot vienu un to pašu ligzdu vairākām garām aptaujām. Praksē viena un tā paša TCP savienojuma saglabāšana gandrīz vienmēr ir vēlamāka veiktspējas uzlabošanai.
Serveriem, kas ievieš garo aptauju, parasti katram klientam ir jāpārvalda divi resursu segmenti: pats TCP savienojums un neapstiprinātais HTTP pieprasījums, kas gaida kādā rindā vai notikumu cilpā. Operētājsistēmas parasti var efektīvi apstrādāt lielu skaitu atvērtu ligzdu, taču daži HTTP serveri vai vārtejas katram pieprasījumam piešķir ievērojamu atmiņas apjomu, kas var kļūt par īsto sašaurinājumu.
Viena interesanta garās aptaujas īpašība ir tā, ka lielas slodzes gadījumā tā mēdz pakāpeniski pasliktināties, palielinot latentumu, nevis radot nopietnas kļūmes. Ja serveris ir lēns, klientam paredzētie ziņojumi tiks rindā, līdz varēs nosūtīt atbildi; vairāki rindā ievietoti notikumi var pat tikt apvienoti vienā garā aptaujas atbildē, kas, starp citu, samazina katra ziņojuma papildu slodzi.
Ilgstošas aptaujas problēmas un ierobežojumi
Lai gan garā aptauja tiek plaši izmantota un standartizēta praksē, tā rada vairākas labi zināmas tehniskas problēmas, kuras, ja neesat uzmanīgs, ir viegli atrisināt, izmantojot JavaScript. Šīs problēmas izpaužas joslas platuma izmantošanā, latentumā, savienojumu pārvaldībā un starpnieku, piemēram, starpniekservera un kešatmiņas, uzvedībā.
Pirmās izmaksas, ar kurām saskaraties, ir galvenes papildu izmaksas: katrs garš aptaujas pieprasījums un atbilde ir pilnīgs HTTP ziņojums, parasti ar sīkfailiem, autorizācijas galvenēm un citiem metadatiem, kas varētu ievērojami palielināt faktisko vērtumu. Maziem, reti nosūtītiem ziņojumiem šīs papildu izmaksas var būt pieņemamas, taču apjoma ziņā balstītos norēķinu scenārijos vai tīklos ar ierobežotu joslas platumu atšķirība starp galvenes lielumu un vērtuma lielumu var kļūt dārga.
Maksimālā latentuma vērtība ir vēl viens smalks jautājums: lai gan vidējais garās aptaujas latentums jauniem notikumiem ir aptuveni viens tīkla tranzīts, sliktākajā gadījumā aizkave var būt vairāk nekā trīs tranzīti. Ja ziņojums pienāk tūlīt pēc tam, kad serveris ir nosūtījis atbildi, serverim ir jāgaida nākamais klienta pieprasījums, pirms tas var piegādāt šo ziņojumu, un TCP pakešu zudums vai atkārtota pārraide var vēl vairāk pagarināt šo laiku.
Savienojuma izveide bieži tiek minēta kā problēma, īpaši, ja cilvēki salīdzina garo aptauju ar WebSockets. Ja katra garā aptaujas atbilde izraisītu HTTP savienojuma (un pamatā esošā TCP savienojuma) slēgšanu, atkārtotas ligzdu atvēršanas izmaksas būtu milzīgas. Par laimi, garo aptauju var un vajag iekļaut pastāvīgo savienojumu virspusē, lai īsais intervāls starp atbildēm netiktu interpretēts kā dīkstāve; tas ļauj transportam palikt atvērtam un atkārtoti izmantojamam.
Servera un starpniekservera resursu piešķiršana ir būtisks praktisks ierobežojums: katrs neizpildīts pieprasījums patērē atmiņu un, iespējams, pavedienu vai darbinieku sinhronajās arhitektūrās. Daudzi vecāki vai bloķējoši serveri vienkārši nav mērogojami līdz desmitiem tūkstošu vienlaicīgu garu aptauju, jo to vienlaicības modelis sagaida, ka katrs pieprasījums tiks ātri pabeigts; šīm sistēmām asinhrona I/O vai notikumu vadīta konstrukcija ir gandrīz obligāta.
Kešatmiņas darbība var arī traucēt garu aptauju izpildi, ja tā nav skaidri apspiesta. Starpnieku kešatmiņas var izlemt atkārtoti izmantot vai saglabāt atbildes, ja vien jūs skaidri neatzīmējat garus aptaujas pieprasījumus un atbildes ar Cache-Control: no-cache (un saistītajām galvenēm), nodrošinot, ka katrs pieprasījums faktiski sasniedz sākotnējo serveri un netiek piegādāti novecojuši dati.
Taimauti, starpniekserveri un starpnieku darbība
Viena no kaitinošākajām reālās pasaules problēmām ar garu aptauju JavaScript valodā ir tā, ka netiek pilnībā kontrolēts tīkls starp pārlūkprogrammu un serveri. Starpniekserveri, vārtejas, slodzes līdzsvarotāji un pat pārlūkprogrammas noklusējuma iestatījumi nosaka taimautus vai buferizācijas stratēģijas, kas var sagraut tiešraides savienojuma ilūziju.
Gariem aptaujas pieprasījumiem ir jāpaliek atvērtiem līdz notikumam vai taimautam, ko kontrolējat, taču patiesībā daudzi starpnieki pārtrauks savienojumus pēc īsāka, fiksēta laika perioda. Lai gan pārlūkprogrammas pēc noklusējuma var atļaut līdz aptuveni 300 sekundēm, daži starpniekserveri piemēro daudz īsākus taimautus, kas nozīmē, ka jūsu garā aptauja tiks pārtraukta ar HTTP 504 vārtejas taimautu vai vienkārši atiestatīšanu, piespiežot klientu atjaunot savienojumu biežāk, nekā jūs bijāt iecerējis.
Eksperimenti un darbības pieredze liecina, ka aptuveni 30 sekunžu taimauti daudzās vidēs ir drošāks kompromiss, savukārt 120 sekundes bieži vien darbojas, bet ir trauslākas. Tīkla iekārtu pārdevējiem, kas vēlas nodrošināt garu aptauju iespējas, ieteicams izmantot taimautus, kas ir ievērojami ilgāki par tipiskiem vidēja lieluma tīkla pārsūtīšanas laikiem, lai likumīgas garas aptaujas netiktu priekšlaicīgi pārtrauktas.
Apgrieztie starpniekserveri un savienojumu apvienošana rada vēl vienu problēmu klasi. Daži starpniekservera iestatījumi koplieto nelielu augšupējo savienojumu kopu starp daudziem klientiem; ja garas aptaujas ilgstoši aizņem šos koplietotos savienojumus, citi pieprasījumi var tikt apturēti vai ievietoti rindā aiz tiem, tādējādi pasliktinot visas vietnes veiktspēju.
Izmantojot HTTP straumēšanu, starpnieka buferizācija rada vēl lielāku risku, jo starpniekservera serveriem ir atļauts buferēt daļējas atbildes un pārsūtīt datus tikai tad, kad tie ir uzkrājuši pilnīgu atbildi. Šādā gadījumā straumēšanas serveris, kas sūta mazus JavaScript fragmentus, sagaidot tūlītēju izpildi pārlūkprogrammā, var atklāt, ka starpniekserveris glabā visu informāciju līdz savienojuma beigām, pilnībā iznīcinot reāllaika darbību.
Pārlūkprogrammas ierobežojumi un savienojumu skaits
No JavaScript nekad netiek tieši manipulēts ar TCP savienojumiem; ir redzamas tikai augsta līmeņa konstrukcijas, piemēram, fetch vai XMLHttpRequest, taču pārlūkprogrammas ievieš ierobežojumus tam, cik paralēlu savienojumu var atvērt ar vienu un to pašu resursdatoru. Vēsturiski šis ierobežojums bija divi savienojumi uz vienu izcelsmi, kas padarīja Comet stila metodes īpaši sarežģītas.
Mūsdienu pārlūkprogrammas ir atvieglojušas šos ierobežojumus līdz aptuveni sešiem vai astoņiem savienojumiem uz vienu resursdatoru, taču joprojām nav standarta veida, kā JavaScript varētu jautāt “cik savienojumu ir atlicis?” vai koordinēt lietojumu starp cilnēm un iframe ietvariem. Katra cilne varētu neatkarīgi izveidot savu garo aptauju, ātri izsmeļot pieejamās vietas un bloķējot citus svarīgus pieprasījumus, piemēram, CSS, attēlu vai API izsaukumus.
Servera pusē labākā prakse ir izmantot sīkfailus vai kādu korelācijas mehānismu, lai noteiktu vairākas garas aptaujas no viena un tā paša pārlūkprogrammas gadījuma un izvairītos no to visu atlikšanas. Ātri reaģējot uz īpaši garām aptaujām un faktiski uzkarinot tikai vienu vai nelielu skaitu, varat samazināt savienojuma trūkuma vai cauruļvada traucējumu risku.
Daži augstāka līmeņa protokoli, kas balstīti uz ilgu aptauju, piemēram, Bayeux un BOSH, skaidri izstrādā protokolus, ņemot vērā pārlūkprogrammas savienojuma ierobežojumus. Tie bieži vien vienlaikus izmanto ne vairāk kā divus neapstiprinātus HTTP pieprasījumus un izvairās no HTTP cauruļvadu izmantošanas, kas ir vāji atbalstīts un ko nevar kontrolēt no JavaScript.
HTTP pipelining, kadrēšana un ziņojumu secība
Lai gan HTTP pipelining (vairāku pieprasījumu nosūtīšana pēc kārtas vienā un tajā pašā savienojumā pirms atbilžu saņemšanas) teorētiski varētu samazināt garo aptaujas latentumu, praksē tā ir nestabila un nekonsekventi ieviesta. RFC 2616 ir piesardzīgs attiecībā uz pipelining, īpaši POST pieprasījumiem, un starpnieki vai klienti to var pilnībā atspējot.
Protokoliem, kas mēģina izmantot cauruļvadu izmantošanu garai aptaujai, vispirms ir jānosaka, vai cauruļvads tiek droši atbalstīts no sākuma līdz beigām; ja nē, tie atgriežas pie konservatīvas, bez cauruļvada darbības. Pārlūkprogrammas JavaScript vidē nav āķu, lai to pārvaldītu, tāpēc lielākā daļa uz JavaScript balstīto garo aptaujas steku vienkārši pieņem, ka cauruļvads nav pieejams.
Kadrēšana — veids, kā nepārtraukta baitu plūsma tiek sadalīta atsevišķos lietojumprogrammu ziņojumos — ir vēl viena neliela atšķirība starp garo aptaujāšanu un HTTP straumēšanu. Izmantojot garo aptaujāšanu, katra HTTP atbilde dabiski satur tieši vienu ziņojumu vai ziņojumu partiju, tāpēc kadrēšana ir netieša: viena atbilde ir vienāda ar vienu jēgpilnu datu fragmentu.
Straumēšanas režīmā lietojumprogrammas kadrēšanā nevar paļauties uz HTTP fragmentu robežām, jo starpniekserveri var atkārtoti sadalīt datu plūsmu fragmentos, apvienot fragmentus vai sadalīt tos citādi. Tas nozīmē, ka lietotnei ir jāiekļauj savi norobežotāji vai garuma prefiksi vērtajā slodzē un attiecīgi jāanalizē tie klientā.
Ziņojumu secību un uzticamību negarantē tikai ilga aptauja; tie ir atkarīgi no jūsu lietojumprogrammas protokola un krātuves slāņa. Ja klients atvienojas un atkārtoti izveido savienojumu straumes vidū, ir nepieciešami skaidri mehānismi (piemēram, secības numuri vai pēdējā notikuma ID), lai nodrošinātu, ka ziņojumi netiek pazaudēti vai piegādāti nepareizā secībā.
Drošības apsvērumi garai aptaujai JavaScript valodā
Ilga aptauja kā metode nemaina HTTP galveno drošības modeli, taču veids, kā tā bieži tiek ieviesta — īpaši pārlūkprogrammās, kas izmanto JavaScript —, var radīt papildu riskus.
Daudzi starpdomēnu garās aptaujas risinājumi balstās uz servera atgrieztā JavaScript koda izpildi, dažreiz izmantojot JSONP stila atzvanīšanas vai citas dinamiskas skriptu injekcijas. Ja jūsu serveris ir neaizsargāts pret injekcijas uzbrukumiem, uzbrucējs var potenciāli ienest patvaļīgu kodu šajās atbildēs, kuras pārlūkprogramma pēc tam palaiž ar lapas privilēģijām.
HTTPS izmantošana visur nav apspriežama: transporta šifrēšana aizsargā pret starpnieka manipulācijām un noklausīšanos ilgstošos savienojumos. Apvienojumā ar stabilu autentifikāciju un autorizāciju (piemēram, uz marķieriem balstītu autentifikāciju un uz lomām balstītu piekļuves kontroli) jūs varat ierobežot garas aptaujas galapunktus paredzētajiem klientiem.
Tā kā garā aptauja ilgstoši uztur daudzus savienojumus atvērtus, tā var padarīt DoS uzbrukumus pievilcīgākus: uzbrucējs var mēģināt noslogot servera resursus, atverot daudzas viltotas garās aptaujas. Ātruma ierobežošana, savienojumu kvotas uz IP adresi vai tokenu un saprātīgi taimauti ir svarīgi aizsardzības pasākumi.
Pārlūkprogrammai specifiski apdraudējumi, piemēram, CSRF, parasti ir mazāk svarīgi tīrām XHR/fetch garajām aptaujām, kas nepaļaujas uz apkārtējās vides sīkfailiem, taču, ja sīkfaili ir iesaistīti, šie galapunkti joprojām ir jāapstrādā tāpat kā jebkurš cits sensitīvs API. SameSite sīkfaili, CSRF žetoni, ja nepieciešams, un stingras CORS politikas ir daļa no pastiprinātas iestatīšanas.
Ilga aptauja salīdzinājumā ar WebSockets un servera nosūtītiem notikumiem
No JavaScript izstrādātāja viedokļa, garās aptaujas, WebSockets un Server-Sent Events ir veidi, kā panākt “reāllaika sajūtas” funkcijas, taču kompromisi diezgan atšķiras.
WebSockets izveido patiesi pastāvīgu, pilna dupleksa kanālu starp pārlūkprogrammu un serveri. Pēc sākotnējās HTTP jaunināšanas saspēles datu kadri var plūst abos virzienos, neradot katram ziņojumam HTTP galvenes, tādējādi samazinot latentumu un joslas platuma izmantošanu.
Tas padara WebSockets ideāli piemērotus augstas frekvences scenārijiem, piemēram, vairāku spēlētāju spēlēm, kopīgai rediģēšanai vai telemetrijas plūsmām, kur ziņojumi ir mazi, bet bieži. Negatīvā puse ir tā, ka daži korporatīvie ugunsmūri, veci starpniekserveri vai mantoti klienti joprojām nedarbojas labi ar WebSocket jauninājumiem, un serveriem ir jāizmanto atšķirīgs programmēšanas modelis un infrastruktūra, kas pielāgota lielam skaitam ilgstoši darbojošos ligzdu.
SSE ir vienkāršāka nekā WebSockets, ja nepieciešama tikai servera-klienta push apmaiņa, taču tā nevar nosūtīt ziņojumus no pārlūkprogrammas atpakaļ pa to pašu kanālu; klienta-servera saziņai joprojām tiek izmantoti parastie HTTP pieprasījumi. Tā arī prasa, lai starpnieki tolerētu straumēšanu un nepārspīlētu daļēju atbilžu buferēšanu.
Salīdzinot ar šīm, garā aptauja bieži vien ir “zemākais kopsaucējs”, kas darbojas vairākās vidēs, tostarp vecākās pārlūkprogrammās un konservatīvos tīkla iestatījumos. Tāpēc daudzas reāllaika platformas vēsturiski izmantoja garo aptauju kā rezerves risinājumu, kad WebSockets tika bloķēti, pakāpeniski uzlabojot savienojumus, kad to ļāva iespējas.
Reālās pasaules protokoli papildus garajām aptaujām: Bayeux, BOSH, SSE līdzīgi API
Vairāki augstāka līmeņa protokoli ir izveidoti, balstoties uz garo aptauju un straumēšanu, lai slēptu sarežģītību no lietojumprogrammu izstrādātājiem un nodrošinātu konsekventu API. Izpratne par to, kā viņi izmanto garo aptauju, palīdz noskaidrot gan šīs metodes stiprās, gan vājās puses.
Bayeux protokols, ko popularizēja CometD projekts, atbalsta gan HTTP garo aptauju, gan straumēšanu kā transporta iespējas. Bayeux klients parasti izmanto divus HTTP savienojumus ar serveri, lai ziņojumi varētu plūst asinhroni abos virzienos, tos nebloķējot garie aptaujas pieprasījumi.
Sākotnējās saziņas laikā klients un serveris vienojas par atbalstītajām divvirzienu metodēm — garo aptauju, straumēšanu utt. —, un klients izvēlas vienu no pārklāšanās metodēm. JavaScript klientiem Bayeux parasti izvairās no HTTP cauruļvadu izmantošanas un tā vietā ierobežo sevi ar diviem neizpildītiem pieprasījumiem, lai izvairītos no pārlūkprogrammas savienojuma ierobežojuma problēmām.
BOSH (Bidirectional-streams Over Synchronous HTTP — divvirzienu straumes pa sinhrono HTTP) nāk no XMPP pasaules un tika izstrādāts, lai emulētu TCP līdzīgu sesiju, izmantojot garo aptauju. BOSH savienojuma pārvaldnieks tur klienta pieprasījumu atvērtu un atbild tikai tad, kad tam ir dati no lietojumprogrammu servera; tiklīdz klients saņem šo atbildi, tas nosūta jaunu pieprasījumu, gandrīz visu laiku saglabājot vismaz vienu gaidošu garo aptauju.
BOSH var izmantot vienu vai divus paralēlus HTTP pieprasījuma-atbildes pārus, kas tiek saskaņoti sesijas sākumā, un rūpīgi tos pārvalda, lai ievērotu pārlūkprogrammas savienojuma ierobežojumus, vienlaikus atļaujot asinhronu divvirzienu ziņojumapmaiņu. Tas aizliedz fragmentētu pārsūtīšanas kodēšanu, lai izvairītos no buferizācijas problēmām starpniekos, un efektivitātes labad atļauj saspiešanu, izmantojot satura kodēšanu.
Servera nosūtītie notikumi, lai gan parasti tiek ieviesti, izmantojot straumēšanu, nevis garu aptauju, pēc būtības ir cieši saistīti. W3C specifikācija apraksta teksta/notikumu straumes atbilžu izmantošanu un iesaka atspējot HTTP fragmentāciju, ja vien notikumu ātrums nav pietiekami augsts, atkal lai izvairītos no noteiktām buferizācijas un starpnieka problēmām, kas rodas straumēšanā, izmantojot HTTP/1.1.
Ilgo aptauju optimizēšana un nostiprināšana JavaScript lietotnēs
Ja izlemjat, ka garā aptauja ir pareizā izvēle vai nepieciešama rezerves iespēja jūsu JavaScript lietotnei, ir vairākas stratēģijas, kā padarīt to efektīvāku, mērogojamāku un robustāku.
Vispirms rūpīgi pielāgojiet taimautus. Pārāk īss laiks nozīmē, ka jūs izšķērdēsiet resursus, apstrādājot biežu atkārtotu savienojumu, un riskēsiet ar klientu pūļiem, kas visi vienlaikus atkārtoti izveidos savienojumu; pārāk ilgs laiks nozīmē, ka palielināsies iespēja sasniegt starpniekservera vai slodzes līdzsvarotāja ierobežojumus, izraisot noslēpumainus savienojumu pārtraukumus. Praksē WaitTimeSeconds vērtības 20–30 sekunžu diapazonā (API, piemēram, Amazon SQS) un līdzīgās lietotņu līmeņa taimautos bieži vien nodrošina labu līdzsvaru.
Tālāk apsveriet notikumu pakešveidošanu servera pusē, ja klientam rindā ir ievietoti vairāki ziņojumi. Vairāku atjauninājumu piegāde vienā garā aptaujas atbildē ievērojami samazina katra ziņojuma papildu slodzi un var palīdzēt sistēmai vienmērīgāk degradēties slodzes apstākļos, aizstājot latentumu ar caurlaidspēju.
Saspiešana ir vēl viens vienkāršs ieguvums: gzip vai līdzīga satura kodējuma iespējošana JSON vērtajām kravām garas aptaujas laikā var samazināt joslas platuma izmantošanu, īpaši, ja ziņojumiem ir kopīga atkārtota struktūra. Kompromiss ir papildu centrālā procesora izmaksas saspiešanai, taču daudzos reālos izvietojumos to kompensē samazināts tīkla pārsūtīšanas laiks.
No JavaScript puses stabila kļūdu apstrāde un atkārtotas mēģināšanas loģika nav apspriežama. Jūsu abonēšanas cilpai ir jānosaka tīkla kļūdas, taimauti vai nepareizi veidotas atbildes un jāmēģina vēlreiz ar pārtraukumu, nevis servera noslodzi. Eksponenciāla pārtraukuma ar svārstībām ir izplatīts modelis, lai novērstu sinhronizētas atkārtotas mēģināšanas vētras pārtraukumu laikā.
Visbeidzot, ievērojiet disciplinētību attiecībā uz savienojuma tīrīšanu, kad komponenti tiek atvienoti vai cilnes tiek aizvērtas. Zombiju aptaujas cikli, kas turpina darboties fonā, var pārtērēt gan klienta resursus, gan servera jaudu, tāpēc vienmēr pārliecinieties, vai jums ir mehānisms, lai atceltu neizpildītas ielādētnes vai priekšlaicīgi pārtrauktu kontrolleru darbību, ja skats tiek iznīcināts vai lietotājs pamet lapu.
Ilga aptauja JavaScript valodā joprojām ir spēcīgs rīks gandrīz reāllaika funkciju izveidei vidēs, kur WebSockets vai SSE nav pieejami, taču tai ir virkne slēptu izmaksu saistībā ar galvenēm, taimautiem, starpniekserveriem un resursu izmantošanu, kas jums ir jāsaprot un jāpārvalda, ja vēlaties, lai jūsu lietotne darbotos vienmērīgi.