Ters basınç uygulayarak uygulamanızın WebSocket mesajlarında boğulmasını veya bir WebSocket sunucusunu iletilerle doldurmasını önleyin.
Arka plan
WebSocket API'si
WebSocket API WebSocket protokolü için bir JavaScript arayüzü sağlar, iki yönlü etkileşimli bir iletişim oturumuna başlamayı mümkün kılar. kullanıcının tarayıcısı ile sunucu arasında. Bu API ile sunucuya mesaj gönderebilir ve etkinliğe dayalı yanıtlar alabilirsiniz yanıt almak için sunucuyu yoklamaya gerek yoktur.
Streams API
Streams API JavaScript'in ağ üzerinden alınan veri parçalarının akışlarına programatik olarak erişmesine olanak tanır bunları istediğiniz gibi işleyebilirsiniz. Akışlar bağlamında önemli bir kavramdır ters basınç. Bu, tek bir akışın veya bir boru zincirinin okuma veya yazma hızını düzenler. Akışın kendisi veya boru zincirinin ilerleyen aşamalarındaki bir akış hâlâ kalabalık olduğunda daha fazla parça kabul etmeye hazır değilse uygun şekilde teslimi yavaşlatmak için zincirden geriye doğru bir sinyal gönderir.
Mevcut WebSocket API'siyle ilgili sorun
Alınan iletilere geri baskı uygulamak imkansız
Geçerli WebSocket API'sinde mesajlara tepki vermek şurada gerçekleşir:
WebSocket.onmessage
Sunucudan bir ileti alındığında bir EventHandler
çağrılır.
Ağır miktarda veri işlemesi yapması gereken bir uygulamanız olduğunu varsayalım.
yeni bir mesaj alırsınız.
Akışı büyük olasılıkla aşağıdaki koda benzer şekilde ayarlarsınız.
process()
aramasının sonucunu await
. Sonuçta başarılı olmalısınız, değil mi?
// A heavy data crunching operation.
const process = async (data) => {
return new Promise((resolve) => {
window.setTimeout(() => {
console.log('WebSocket message processed:', data);
return resolve('done');
}, 1000);
});
};
webSocket.onmessage = async (event) => {
const data = event.data;
// Await the result of the processing step in the message handler.
await process(data);
};
Yanlış! Mevcut WebSocket API'deki sorun, karşı basınç uygulamanın bir yolunun olmamasıdır.
İletiler, process()
yönteminin işleyebileceğinden daha hızlı ulaştığında
oluşturma işlemi, bu mesajları arabelleğe alarak belleği kaplar.
veya her iki nedenden dolayı yanıt vermemeye başlar.
Gönderilen iletilere karşı basınç uygulamak ergonomik değildir
Gönderilen iletilere karşı baskı uygulamak mümkündür ancak
WebSocket.bufferedAmount
verimsiz ve ergonomik olmayan özelliklere sahiptir.
Bu salt okunur özellik, sıraya alınmış verilerin bayt sayısını döndürür.
kullanarak
WebSocket.send()
ancak henüz ağa iletilmemiştir.
Sıradaki tüm veriler gönderildikten sonra bu değer sıfırlanır.
ancak WebSocket.send()
adlı kişiyi aramaya devam ederseniz
artmaya devam edecek.
WebSocketStream API nedir?
WebSocketStream API, var olmayan veya ergonomik olmayan karşı basınç sorununu ele alır. WebSocket API ile akışları entegre ederek Bu, baskının herhangi bir ek maliyet olmadan "ücretsiz" olarak uygulanabileceği anlamına gelir.
WebSocketStream API için önerilen kullanım alanları
Bu API'yi kullanılabilecek sitelere örnek olarak şunlar verilebilir:
- Etkileşimi koruması gereken, yüksek bant genişliğine sahip WebSocket uygulamaları özellikle de video ve ekran paylaşımı.
- Benzer şekilde, video yakalama ve tarayıcıda büyük miktarda veri üreten diğer uygulamalar yüklenmesi gereken bir dosyadır. Karşı basınç sayesinde istemci, verileri bellekte biriktirmek yerine veri üretmeyi durdurabilir.
Mevcut durum
Step | Durum |
---|---|
1. Açıklayıcı oluşturun | Tamamlandı |
2. İlk spesifikasyon taslağını oluşturun | Devam ediyor |
3. Geri bildirim toplama tasarımı yineleyin | Devam ediyor |
4. Kaynak denemesi | Tamamlandı |
5. Başlat | Başlatılmadı |
WebSocketStream API'yi kullanma
Tanıtım örneği
WebSocketStream API vaat temellidir, bu da doğal bir şekilde işlem yapılmasını sağlar
bir araya getirmektir.
Yeni bir WebSocketStream
oluşturup bunu WebSocket sunucusunun URL'sini ileterek başlarsınız.
Sonra, bağlantının opened
olmasını beklersiniz.
Bu da
ReadableStream
ve/veya
WritableStream
.
ReadableStream.getReader()
yöntemini kullanarak, nihayet
ReadableStreamDefaultReader
,
Ardından read()
veri akışı tamamlanana kadar, yani formda bir nesne döndürene kadar
{value: undefined, done: true}
Buna uygun olarak,
WritableStream.getWriter()
yöntemini kullanarak, nihayet
WritableStreamDefaultWriter
,
Ardından write()
.
const wss = new WebSocketStream(WSS_URL);
const {readable, writable} = await wss.opened;
const reader = readable.getReader();
const writer = writable.getWriter();
while (true) {
const {value, done} = await reader.read();
if (done) {
break;
}
const result = await process(value);
await writer.write(result);
}
Sızıntı
Söz edilen karşı baskı özelliğine ne olacak?
Yukarıda da belirttiğim gibi, ek bir işlem yapmanıza gerek kalmadan "ücretsiz" olarak yararlanabilirsiniz.
process()
daha fazla zaman alırsa sonraki mesaj yalnızca ardışık düzen hazır olduğunda kullanılır.
Benzer şekilde, WritableStreamDefaultWriter.write()
adımı
güvenli olduğu durumlarda işleme devam eder.
Gelişmiş örnekler
WebSocketStream'in ikinci bağımsız değişkeni, gelecekte uzatmaya olanak tanıyan bir seçenek çantasıdır.
Şu anda tek seçenek protocols
.
her zaman
WebSocket kurucusu için ikinci bağımsız değişken:
const chatWSS = new WebSocketStream(CHAT_URL, {protocols: ['chat', 'chatv2']});
const {protocol} = await chatWSS.opened;
Seçilen protocol
ve potansiyel extensions
sözlüğün bir parçası
WebSocketStream.opened
taahhüdüyle sunuluyor.
Canlı bağlantıyla ilgili tüm bilgiler bu söz ile sağlanmaktadır.
çünkü bağlantının başarısız olmasıyla ilgili değildir.
const {readable, writable, protocol, extensions} = await chatWSS.opened;
Kapalı WebSocketStream bağlantısı hakkında bilgi
Söz konusu
WebSocket.onclose
ve
WebSocket.onerror
etkinlik
özellikleri artık WebSocketStream.closed
sözü ile kullanılabilmektedir.
Hatalı bir kapanış olması halinde vaat reddedilir.
aksi takdirde, sunucu tarafından gönderilen koda ve nedene çözümlenir.
Olası tüm durum kodları ve anlamları şurada açıklanmıştır:
CloseEvent
durum kodlarının listesi.
const {code, reason} = await chatWSS.closed;
WebSocketStream bağlantısını kapatma
WebSocketStream, bir
AbortController
.
Bu nedenle, bir AbortSignal
WebSocketStream
oluşturucusuna gönderilir.
const controller = new AbortController();
const wss = new WebSocketStream(URL, {signal: controller.signal});
setTimeout(() => controller.abort(), 1000);
Alternatif olarak, WebSocketStream.close()
yöntemini de kullanabilirsiniz
fakat asıl amacı,
kod
ve sunucuya gönderilme nedeni.
wss.close({code: 4000, reason: 'Game over'});
Progresif geliştirme ve birlikte çalışabilirlik
Chrome şu anda WebSocketStream API'yi uygulayan tek tarayıcıdır.
Klasik WebSocket API ile birlikte çalışabilirlik için
alınan mesajlara geri baskı uygulanamıyor.
Gönderilen iletilere karşı baskı uygulamak mümkündür ancak
WebSocket.bufferedAmount
verimsiz ve ergonomik olmayan özelliklere sahiptir.
Özellik algılama
WebSocketStream API'nin desteklenip desteklenmediğini kontrol etmek için şunu kullanın:
if ('WebSocketStream' in window) {
// `WebSocketStream` is supported!
}
Demo
Desteklenen tarayıcılarda WebSocketStream API'yi yerleşik iframe'de iş başında görebilirsiniz. doğrudan Glitch'te paylaşabilirsiniz.
Geri bildirim
Chrome ekibi, WebSocketStream API deneyimleriniz hakkında bilgi almak istiyor.
Bize API tasarımı hakkında bilgi verin
API'de beklediğiniz gibi çalışmayan bir şey mi var? Yoksa fikrinizi uygulamak için ihtiyacınız olan eksik yöntemler veya özellikler mi var? Güvenlik modeliyle ilgili bir sorunuz veya yorumunuz mu var? İlgili GitHub deposunda bir spesifikasyon sorunu bildirin, veya düşüncelerinizi mevcut bir soruna ekleyebilirsiniz.
Uygulamayla ilgili bir sorunu bildirin
Chrome'un uygulanmasıyla ilgili bir hata buldunuz mu?
Yoksa uygulama, spesifikasyondan farklı mı?
new.crbug.com adresinden hata bildiriminde bulunun.
Ürünün yeniden üretilmesine ilişkin mümkün olduğunca çok ayrıntı, basit talimatlar,
Bileşenler kutusuna Blink>Network>WebSockets
yazın.
Glitch, yeniden oluşturma vakalarını hızlı ve kolay bir şekilde paylaşmak için idealdir.
API'ye desteğinizi gösterin
WebSocketStream API'yi kullanmayı planlıyor musunuz? Herkese açık desteğiniz, Chrome ekibinin özelliklere öncelik vermesine yardımcı olur ve diğer tarayıcı tedarikçilerine, onları desteklemenin ne kadar önemli olduğunu gösteriyor.
Hashtag'i kullanarak @ChromiumDev hesabına tweet gönderin
#WebSocketStream
ve nerede ve nasıl kullandığınızı bize bildirin.
Faydalı bağlantılar
- Herkese açık açıklayıcı
- WebSocketStream API Demosu | WebSocketStream API Demo kaynağı
- Hata izleme
- ChromeStatus.com girişi
- Blink Bileşeni:
Blink>Network>WebSockets
Teşekkür
WebSocketStream API, Adam Rice tarafından uygulanmıştır ve Yutaka Hirano Daan Mooij'in hero resmi Lansmanı kaldırın.