websockets'in 1006 yakın koduyla kapatılmasının nedenini öğrenmek


92

Kullanıcıya doğru mesajı gösterebilmem için web soketlerinin neden kapalı olduğunu öğrenmek istiyorum.

Sahibim

sok.onerror=function (evt) 
     {//since there is an error, sockets will close so...
       sok.onclose=function(e){
           console.log("WebSocket Error: " , e);}

Kod her zaman 1006'dır ve nedeni her zaman "" dir. Ancak farklı kapanış nedenlerini ayrı ayrı anlatmak istiyorum.

Örneğin, komut satırı bir hata nedeni verir: "Bunu silemezsiniz, çünkü veritabanı size izin vermez". Ancak Chrome konsolunda neden hala "".

Farklı kapanış nedenlerini birbirinden ayırmanın başka bir yolu var mı?


Sanırım bunun nedeni, sunucunun bağlı / bağlantısız olayları işleme biçimi. Kesin olarak söyleyemem, ancak bağlantı kapatma işleminin sunucuda da kodla doğru şekilde işlenmesi gerekiyor. Sunucudaki yerleşik On Connected / Disconnected yöntemlerini geçersiz kılmayı deneyin ve bakın. Benim varsayımım, onu kapattığınız, ancak sunucunun düzgün şekilde kapanmaması ve bu nedenle uygun kapalı yanıtı iletmemesi.
Michael Puckett II

Yanıtlar:


124

Kapat Kodu1006 , bağlantının tarayıcı uygulaması tarafından anormal şekilde (yerel olarak) kapatıldığı anlamına gelen özel bir koddur.

Tarayıcı istemciniz kapanış kodunu rapor ederse, ayrıntılar 1006için websocket.onerror(evt)etkinliğe bakmanız gerekir .

Ancak Chrome, yakın kod 1006nedenlerini Javascript tarafına nadiren bildirir . Bunun nedeni, WebSocket'in kötüye kullanılmasını önlemek için WebSocket spesifikasyonundaki istemci güvenlik kurallarından kaynaklanmaktadır. (bir hedef sunucuda açık bağlantı noktalarını taramak veya hizmet reddi saldırısı için çok sayıda bağlantı oluşturmak için kullanmak gibi).

1006HTTP'nin Websocket'e Yükseltmesi sırasında bir hata olması durumunda Chrome'un genellikle bir kapanış kodu bildireceğini unutmayın (bu, WebSocket'in teknik olarak "bağlanmasından" önceki adımdır). Kötü kimlik doğrulama veya yetkilendirme ya da kötü protokol kullanımı gibi nedenlerle (örneğin bir alt protokol istemek, ancak sunucunun kendisi aynı alt protokolü desteklemiyor) veya hatta WebSocket olmayan bir sunucu konumuyla konuşma girişimi ( bağlanmaya çalışmak gibi ws://images.google.com/)

Temel olarak, yakın bir kod 1006görürseniz, WebSocket'in kendisiyle ilgili çok düşük düzeyde bir hatanız var ("Dosya Açılamıyor" veya "Soket Hatası" na benzer), düşük düzeyli bir soruna işaret ettiği için gerçekten kullanıcı için değildir. kodunuz ve uygulamanızla. Düşük seviyeli sorunlarınızı giderin ve ardından bağlandığınızda daha makul hata kodlarını ekleyebilirsiniz. Bunu projenizde kapsam veya önem açısından başarabilirsiniz. Örnek: bilgi ve uyarı seviyesi, projenizin özel protokolünün bir parçasıdır ve bağlantının kesilmesine neden olmaz. Ciddi veya ölümcül mesajlar ile raporlama, istediğiniz kadar ayrıntı iletmek için projenizin protokolünü kullanarak ve ardından WebSocket yakın akışının sınırlı yeteneklerini kullanarak bağlantıyı kapatın.

WebSocket kapatma kodlarının çok katı bir şekilde tanımlandığını ve yakın neden deyimi / mesajının uzunluğu 123 karakteri geçemeyeceğini unutmayın (bu, kasıtlı bir WebSocket sınırlamasıdır).

Ancak, bu bilgileri yalnızca hata ayıklama nedenleriyle istiyorsanız, kapatmanın ayrıntıları ve bunun altında yatan neden genellikle Chrome'un Javascript konsolunda makul miktarda ayrıntıyla bildirilir.


4
Joakim, teşekkürler, çok detaylı cevaplayıcı. sok.onerror=function (evt) {console.log(evt);}Ayrıntıları kullanırsam çok fazla değil. Hatta bir reasonşey değil. Yani hiç seçenek yok mu? Sadece kullanıcıya gösteriyorum, something is wrong, or not connencted?Çok kullanıcı dostu değil, kullanıcının "Silemezsiniz, veritabanı kısıtlamaları nedeniyle" görmesi güzel olur. Herhangi bir seçenek var mı? Teşekkürler
slevin

Bunun sok.oncloseyerine hangi tetikleyicileri kullanmalısınız close event, içinde reasonve codeiçinde
Ihab Khattab

@IhabKhattab yakın koda özgü olacak ve ayrıca kapanma gerçekleştiğinde. sahip olmak sok.onclosebirçok yol için işe yarayacaktır, ancak tüm yollar için değil. Özellikle kötü protokol, kötü el sıkışma hataları (yakın koda neden olabilecek bazı koşullar gibi 1006). Bu gelecekte değişecek mi? Muhtemelen. Ancak bu cevap yazıldığında doğruydu.
Joakim Erdfelt

@JoakimErdfelt özür dilerim, @slevin'e reasonkullandığında geri dönüşü olmadığı sorusuna yanıt veriyordum onerror. Bu özelliklerin codeve olaya reasonözgü closeolaya özgü olmadığını belirtiyordum error. onunonclose yerine kullanması daha iyi olur , bir şey mi kaçırıyorum?
Ihab Khattab

@IhabKhattab evet, sorusu 1006özel bir anlamı olan hata kodu ve websocket spesifikasyonundaki özel işleme ve javascript websocket api ile ilgili özeldi. Bazı 1006koşullar altında neden dizesi / mesajı , API'nin hiçbir yerinde özel ve kasıtlı olarak açığa çıkmaz. (cevabın işaret ettiği gibi). Bu, API'deki bir hata değildir, yalnızca çeşitli özellikleri ve web soketinin websocket dışı amaçlarla kötüye kullanılması konusundaki endişelerini ele alır.
Joakim Erdfelt

16

Benim ve muhtemelen @BIOHAZARD davamda öyleydi nginx proxy timeout. Varsayılan olarak 60, sokette etkinlik olmadan saniyedir

24 saat içinde değiştirdim nginxve sorunu çözdü

proxy_read_timeout 86400s;
proxy_send_timeout 86400s;

Bunun için teşekkürler! Benim durumumdaki 1006 hatasının nedeni budur.
Steve Hanov

11

Chrome'un WebSocket standardıyla uyumlu olmadığı durum böyle görünüyor. Ne zaman sunucu inisiyeler kapatın ve bir müşteriye yakın çerçeve gönderir Chrome bu bir hata olarak değerlendirdiği ve kod 1006 ve hiçbir neden mesaj ile JS tarafa bildirir. Testlerimde Chrome, sunucu tarafından başlatılan yakın çerçevelere (yakın kod 1000) hiçbir zaman yanıt vermiyor, bu da 1006 kodunun muhtemelen Chrome'un kendi dahili hatasını bildirdiği anlamına geldiğini gösteriyor.

PS Firefox v57.00 bu durumu düzgün bir şekilde ele alır ve sunucunun neden mesajını JS tarafına başarıyla iletir.


3

Bunun diğerleri için kullanışlı olabileceğini düşündüm. Normal ifadeyi bilmek yararlıdır çocuklar. Okulda kal.

Düzenleme: Kullanışlı bir züppe işleve dönüştürdü!

let specificStatusCodeMappings = {
    '1000': 'Normal Closure',
    '1001': 'Going Away',
    '1002': 'Protocol Error',
    '1003': 'Unsupported Data',
    '1004': '(For future)',
    '1005': 'No Status Received',
    '1006': 'Abnormal Closure',
    '1007': 'Invalid frame payload data',
    '1008': 'Policy Violation',
    '1009': 'Message too big',
    '1010': 'Missing Extension',
    '1011': 'Internal Error',
    '1012': 'Service Restart',
    '1013': 'Try Again Later',
    '1014': 'Bad Gateway',
    '1015': 'TLS Handshake'
};

function getStatusCodeString(code) {
    if (code >= 0 && code <= 999) {
        return '(Unused)';
    } else if (code >= 1016) {
        if (code <= 1999) {
            return '(For WebSocket standard)';
        } else if (code <= 2999) {
            return '(For WebSocket extensions)';
        } else if (code <= 3999) {
            return '(For libraries and frameworks)';
        } else if (code <= 4999) {
            return '(For applications)';
        }
    }
    if (typeof(specificStatusCodeMappings[code]) !== 'undefined') {
        return specificStatusCodeMappings[code];
    }
    return '(Unknown)';
}

Kullanım:

getStatusCodeString(1006); //'Abnormal Closure'

{
    '0-999': '(Unused)',
    '1016-1999': '(For WebSocket standard)',
    '2000-2999': '(For WebSocket extensions)',
    '3000-3999': '(For libraries and frameworks)',
    '4000-4999': '(For applications)'
}

{
    '1000': 'Normal Closure',
    '1001': 'Going Away',
    '1002': 'Protocol Error',
    '1003': 'Unsupported Data',
    '1004': '(For future)',
    '1005': 'No Status Received',
    '1006': 'Abnormal Closure',
    '1007': 'Invalid frame payload data',
    '1008': 'Policy Violation',
    '1009': 'Message too big',
    '1010': 'Missing Extension',
    '1011': 'Internal Error',
    '1012': 'Service Restart',
    '1013': 'Try Again Later',
    '1014': 'Bad Gateway',
    '1015': 'TLS Handshake'
}

Kaynak (kısalık için küçük düzenlemelerle): https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes


1

İstemci olarak Chrome ve nginx proxy altında sunucu olarak golang gorilla websocket kullanırken hata aldım

Ve çözülen her x saniyede bir sunucudan istemciye bir "ping" mesajı göndermek


0

Bu, cihazda kullandığınız websocket URL'niz olabilir, aynı olmayabilir (android / iphonedevice'den farklı websocket URL'sine basıyorsunuz)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.