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?
javascript
websocket
slevin
sumber
sumber
Jawaban:
Kode Tutup
1006
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 melihatwebsocket.onerror(evt)
acara tersebut untuk detailnya.Namun, Chrome jarang melaporkan
1006
alasan 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
1006
jika 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 kews://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.
sumber
sok.onerror=function (evt) {console.log(evt);}
detailnya tidak begitu banyak. Bahkan tidakreason
atau 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 kasihsok.onclose
pemicu yang manaclose event
, yang memilikireason
dancode
di dalamnyasok.onclose
akan bekerja untuk banyak jalur, tetapi tidak semua jalur. Terutama protokol yang buruk, kesalahan jabat tangan yang buruk (seperti beberapa kondisi yang dapat menyebabkan kode tutup1006
). Akankah ini berubah di masa depan? Mungkin. Tetapi ketika jawaban ini ditulis, itu benar.reason
kembali ketika dia menggunakanonerror
Saya menunjukkan bahwa properti inicode
&reason
khusus untukclose
acara bukanerror
acara. jadi akan lebih baik baginya untuk menggunakanonclose
, apakah aku melewatkan sesuatu?1006
yang memiliki arti khusus, dan penanganan khusus di spek websocket, dan javascript websocket api. Alasan string / pesan dalam beberapa1006
kondisi 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.Dalam kasus saya dan mungkin @BIOHAZARD
nginx proxy timeout
. Secara default, ini adalah60
detik tanpa aktivitas di soketSaya mengubahnya menjadi 24 jam
nginx
dan itu menyelesaikan masalahproxy_read_timeout 86400s; proxy_send_timeout 86400s;
sumber
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.
sumber
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
sumber
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
sumber
Ini mungkin URL websocket Anda yang Anda gunakan di perangkat tidak sama (Anda menekan URL websocket yang berbeda dari android / iphonedevice)
sumber