mendapatkan alasan mengapa websockets ditutup dengan kode tutup 1006

92

Saya ingin mengetahui alasan penutupan websockets, sehingga saya dapat menampilkan pesan yang tepat kepada pengguna.

saya sudah

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

Kode selalu 1006 dan alasannya selalu "". Tapi saya ingin menjelaskan alasan penutupan yang berbeda.

Misalnya baris perintah memberikan alasan kesalahan: "Anda tidak dapat menghapusnya, karena database tidak mengizinkan Anda". Namun di konsol Chrome, alasannya masih "".

Adakah cara lain untuk membedakan alasan penutupan yang berbeda?

slevin
sumber
Saya pikir ini karena cara server menangani peristiwa yang terhubung / terputus. Saya tidak bisa mengatakan dengan pasti tetapi penutupan koneksi perlu ditangani dengan benar di server juga dengan kode. Coba ganti metode built in On Connected / Disconnected di server dan lihat. Asumsi saya hanya Anda menutupnya tetapi server tidak menutup dengan benar dan karena itu tidak menyampaikan respons tertutup yang tepat.
Michael Puckett II

Jawaban:

124

Kode Tutup1006 adalah kode khusus yang berarti koneksi ditutup secara tidak normal (secara lokal) oleh implementasi browser.

Jika klien browser Anda melaporkan kode tutup 1006, maka Anda harus melihat websocket.onerror(evt)acara tersebut untuk detailnya.

Namun, Chrome jarang melaporkan 1006alasan kode dekat apa pun ke sisi Javascript. Ini mungkin karena aturan keamanan klien dalam spesifikasi WebSocket untuk mencegah penyalahgunaan WebSocket. (seperti menggunakannya untuk memindai port yang terbuka di server tujuan, atau untuk menghasilkan banyak koneksi untuk serangan denial-of-service).

Perhatikan bahwa Chrome akan sering melaporkan kode tutup 1006jika ada kesalahan selama Peningkatan HTTP ke Websocket (ini adalah langkah sebelum WebSocket secara teknis "terhubung"). Untuk alasan seperti otentikasi atau otorisasi yang buruk, atau penggunaan protokol yang buruk (seperti meminta subprotokol, tetapi server itu sendiri tidak mendukung subprotokol yang sama), atau bahkan upaya untuk berbicara dengan lokasi server yang bukan WebSocket ( seperti mencoba menyambung ke ws://images.google.com/)

Pada dasarnya, jika Anda melihat kode tutup 1006, Anda memiliki tingkat kesalahan yang sangat rendah dengan WebSocket itu sendiri (mirip dengan "Tidak Dapat Membuka File" atau "Kesalahan Soket"), tidak benar-benar dimaksudkan untuk pengguna, karena ini menunjukkan masalah tingkat rendah dengan kode dan implementasi Anda. Perbaiki masalah tingkat rendah Anda, dan kemudian saat Anda tersambung, Anda dapat menyertakan kode kesalahan yang lebih masuk akal. Anda dapat mencapai ini dalam hal cakupan atau tingkat keparahan dalam proyek Anda. Contoh: info dan tingkat peringatan adalah bagian dari protokol khusus proyek Anda, dan tidak menyebabkan koneksi terputus. Dengan pelaporan pesan yang parah atau fatal juga menggunakan protokol proyek Anda untuk menyampaikan detail sebanyak yang Anda inginkan, lalu menutup koneksi menggunakan kemampuan terbatas aliran penutupan WebSocket.

Ketahuilah bahwa kode dekat WebSocket ditentukan dengan sangat ketat, dan alasan penutup frasa / pesan tidak boleh melebihi 123 karakter (ini adalah batasan WebSocket yang disengaja).

Tetapi tidak semua hilang, jika Anda hanya menginginkan informasi ini untuk alasan debugging, detail penutupan, dan alasan yang mendasarinya sering dilaporkan dengan cukup detail di konsol Javascript Chrome.

Joakim Erdfelt
sumber
4
Joakim, terima kasih, jawaban yang sangat rinci. Kalau saya pakai sok.onerror=function (evt) {console.log(evt);}detailnya tidak begitu banyak. Bahkan tidak reasonatau sesuatu. Jadi, tidak ada pilihan sama sekali? Saya hanya menunjukkan kepada pengguna, something is wrong, or not connencted?Tidak begitu ramah pengguna, alangkah baiknya jika pengguna dapat melihat "Anda tidak dapat menghapus, karena pembatasan database". Ada pilihan? Terima kasih
slevin
Anda harus menggunakan sok.onclosepemicu yang mana close event, yang memiliki reasondan codedi dalamnya
Ihab Khattab
@IhabKhattab yang akan menjadi kode khusus dekat, dan juga saat penutupan terjadi. memiliki sok.oncloseakan bekerja untuk banyak jalur, tetapi tidak semua jalur. Terutama protokol yang buruk, kesalahan jabat tangan yang buruk (seperti beberapa kondisi yang dapat menyebabkan kode tutup 1006). Akankah ini berubah di masa depan? Mungkin. Tetapi ketika jawaban ini ditulis, itu benar.
Joakim Erdfelt
@JoakimErdfelt maaf, saya membalas pertanyaan @slevin tentang dia tidak reasonkembali ketika dia menggunakan onerrorSaya menunjukkan bahwa properti ini code& reasonkhusus untuk closeacara bukan erroracara. jadi akan lebih baik baginya untuk menggunakan onclose, apakah aku melewatkan sesuatu?
Ihab Khattab
@IhabKhattab ya, karena pertanyaannya spesifik tentang kode error 1006yang memiliki arti khusus, dan penanganan khusus di spek websocket, dan javascript websocket api. Alasan string / pesan dalam beberapa 1006kondisi secara khusus dan sengaja tidak diekspos di mana pun di API. (seperti jawaban yang ditunjukkan). Ini bukan bug di API, ini hanya menangani berbagai spesifikasi dan kekhawatiran mereka seputar penyalahgunaan websocket untuk tujuan non-websocket.
Joakim Erdfelt
16

Dalam kasus saya dan mungkin @BIOHAZARD nginx proxy timeout. Secara default, ini adalah 60detik tanpa aktivitas di soket

Saya mengubahnya menjadi 24 jam nginxdan itu menyelesaikan masalah

proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
MixerOID
sumber
Terima kasih untuk ini! Itu adalah alasan kesalahan 1006 dalam kasus saya.
Steve Hanov
11

Sepertinya ini adalah kasus ketika Chrome tidak sesuai dengan standar WebSocket. Saat server mulai menutup dan mengirim bingkai dekat ke klien, Chrome menganggap ini sebagai kesalahan dan melaporkannya ke sisi JS dengan kode 1006 dan pesan tanpa alasan. Dalam pengujian saya, Chrome tidak pernah menanggapi bingkai dekat yang dimulai server (kode tutup 1000) yang menunjukkan bahwa kode 1006 mungkin berarti bahwa Chrome melaporkan kesalahan internalnya sendiri.

PS Firefox v57.00 menangani kasus ini dengan baik dan berhasil mengirimkan pesan alasan server ke sisi JS.

pengguna10663464
sumber
3

Pikir ini mungkin berguna untuk orang lain. Mengetahui regex itu berguna, anak-anak. Tetap di sekolah.

Sunting: Ubah itu menjadi fungsi keren yang berguna!

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)';
}

Pemakaian:

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'
}

Sumber (dengan sedikit pengeditan untuk kesederhanaan): https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes

Andrew
sumber
1

Saya mendapat kesalahan saat menggunakan Chrome sebagai klien dan golang gorilla websocket sebagai server di bawah proxy nginx

Dan mengirimkan hanya beberapa pesan "ping" dari server ke klien setiap x detik menyelesaikan masalah

BIOHAZARD
sumber
0

Ini mungkin URL websocket Anda yang Anda gunakan di perangkat tidak sama (Anda menekan URL websocket yang berbeda dari android / iphonedevice)

Ankush Sahu
sumber