tìm hiểu lý do tại sao websockets đóng với mã đóng 1006


92

Tôi muốn biết lý do websockets đóng, để tôi có thể hiển thị thông báo phù hợp cho người dùng.

Tôi có

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

Mã luôn là 1006 và lý do luôn là "". Nhưng tôi muốn nói ra những lý do đóng cửa khác nhau.

Ví dụ dòng comand đưa ra lý do lỗi: "bạn không thể xóa nó, vì cơ sở dữ liệu sẽ không cho phép bạn". Nhưng trên bảng điều khiển của Chrome, lý do vẫn là "".

Có cách nào khác để phân biệt các lý do đóng cửa khác nhau không?


Tôi nghĩ điều này là do cách máy chủ đang xử lý các sự kiện được kết nối / ngắt kết nối. Tôi không thể nói chắc chắn nhưng việc đóng kết nối cần được xử lý chính xác trên máy chủ cũng bằng mã. Hãy thử ghi đè các phương pháp On Connected / Disconnected được tích hợp sẵn trên máy chủ và xem. Giả định của tôi chỉ là bạn đang đóng nó nhưng máy chủ không đóng đúng cách và do đó không chuyển tiếp phản hồi đã đóng thích hợp.
Michael Puckett II

Câu trả lời:


124

1006 đóng là một mã đặc biệt có nghĩa là kết nối đã bị đóng bất thường (cục bộ) bởi việc triển khai trình duyệt.

Nếu ứng dụng khách trình duyệt của bạn báo cáo mã đóng 1006, thì bạn nên xem websocket.onerror(evt)sự kiện để biết chi tiết.

Tuy nhiên, Chrome sẽ hiếm khi báo cáo bất kỳ 1006lý do đóng mã nào cho phía Javascript. Điều này có thể là do các quy tắc bảo mật của máy khách trong thông số kỹ thuật WebSocket để ngăn việc lạm dụng WebSocket. (chẳng hạn như sử dụng nó để quét các cổng đang mở trên máy chủ đích hoặc để tạo nhiều kết nối cho một cuộc tấn công từ chối dịch vụ).

Lưu ý rằng Chrome thường sẽ báo cáo mã đóng 1006nếu có lỗi trong quá trình Nâng cấp HTTP lên Websocket (đây là bước trước khi WebSocket được "kết nối" về mặt kỹ thuật). Vì các lý do như xác thực hoặc ủy quyền không hợp lệ, hoặc sử dụng giao thức không hợp lệ (chẳng hạn như yêu cầu giao thức con nhưng bản thân máy chủ không hỗ trợ giao thức con đó) hoặc thậm chí cố gắng nói chuyện với vị trí máy chủ không phải là WebSocket ( chẳng hạn như cố gắng kết nối với ws://images.google.com/)

Về cơ bản, nếu bạn thấy một mã đóng 1006, tức là bạn đã gặp lỗi cấp độ rất thấp với chính WebSocket (tương tự như "Không thể mở tệp" hoặc "Lỗi ổ cắm"), không thực sự dành cho người dùng, vì nó chỉ ra một vấn đề cấp thấp với mã và cách triển khai của bạn. Khắc phục sự cố cấp thấp của bạn và sau đó khi bạn được kết nối, bạn có thể bao gồm các mã lỗi hợp lý hơn. Bạn có thể thực hiện điều này về phạm vi hoặc mức độ nghiêm trọng trong dự án của mình. Ví dụ: thông tin và mức cảnh báo là một phần của giao thức cụ thể của dự án của bạn và không làm cho kết nối bị chấm dứt. Với các thông báo nghiêm trọng hoặc nghiêm trọng, báo cáo cũng sử dụng giao thức dự án của bạn để truyền tải nhiều thông tin chi tiết như bạn muốn, sau đó đóng kết nối bằng các khả năng hạn chế của luồng đóng WebSocket.

Lưu ý rằng mã đóng của WebSocket được xác định rất nghiêm ngặt và cụm từ / thông báo lý do đóng không được dài quá 123 ký tự (đây là một giới hạn cố ý của WebSocket).

Nhưng không phải tất cả đều bị mất, nếu bạn chỉ muốn thông tin này vì lý do gỡ lỗi, chi tiết của việc đóng và lý do cơ bản của nó thường được báo cáo với một lượng chi tiết khá trong bảng điều khiển Javascript của Chrome.


4
Joakim, cảm ơn, anser rất chi tiết. Nếu tôi sử dụng sok.onerror=function (evt) {console.log(evt);}các chi tiết không quá nhiều. Thậm chí không phải là một reasonhoặc một cái gì đó. Vì vậy, không có lựa chọn nào cả? Tôi chỉ hiển thị cho người dùng, something is wrong, or not connencted?Không thân thiện với người dùng, sẽ rất tuyệt nếu người dùng có thể nhìn thấy "Bạn không thể xóa, nguyên nhân do hạn chế cơ sở dữ liệu". Có tùy chọn nào không? Cảm ơn
slvin

Bạn nên sử dụng sok.onclosethay vì đó trigger close event, nó có reasoncodetrong nó
Ihab Khattab

@IhabKhattab sẽ là mã đóng cụ thể và cả khi quá trình đóng xảy ra. có sok.onclosesẽ làm việc cho nhiều con đường, nhưng không phải tất cả các con đường. Đặc biệt là giao thức tồi, lỗi bắt tay không tốt (như một số điều kiện có thể gây ra đóng mã 1006). Liệu điều này có thay đổi trong tương lai? Có lẽ. Nhưng khi câu trả lời này được viết ra thì nó là sự thật.
Joakim Erdfelt

@JoakimErdfelt xin lỗi, tôi đã trả lời câu hỏi của @slevin về việc anh ấy đã không reasontrả lại khi anh ấy sử dụng. onerrorTôi đã chỉ ra rằng thuộc tính này code& reasoncụ thể cho closesự kiện không phải errorsự kiện. vì vậy tốt hơn là anh ta nên sử dụng onclosethay thế, tôi có thiếu thứ gì đó không?
Ihab Khattab

@IhabKhattab vâng, vì câu hỏi của anh ấy là cụ thể về mã lỗi 1006có ý nghĩa đặc biệt và cách xử lý đặc biệt trong thông số kỹ thuật websocket và api websocket javascript. Chuỗi lý do / thông báo trong một số 1006điều kiện không được hiển thị cụ thể và có chủ ý ở bất kỳ đâu trong API. (như câu trả lời đã chỉ ra). Đây không phải là một lỗi trong API, nó chỉ giải quyết các thông số kỹ thuật khác nhau và mối quan tâm của họ xung quanh việc lạm dụng websocket cho các mục đích không phải websocket.
Joakim Erdfelt

15

Trong trường hợp @BIOHAZARD của tôi và có thể là như vậy nginx proxy timeout. Theo mặc định, đó là 60giây không có hoạt động trong ổ cắm

Tôi đã thay đổi nó thành 24h trong nginxvà nó đã giải quyết được sự cố

proxy_read_timeout 86400s;
proxy_send_timeout 86400s;

Cám ơn vì cái này! Đó là lý do cho lỗi 1006 trong trường hợp của tôi.
Steve Hanov

11

Có vẻ như đây là trường hợp Chrome không tuân thủ tiêu chuẩn WebSocket. Khi máy chủ bắt đầu đóng và gửi khung đóng tới máy khách, Chrome sẽ coi đây là lỗi và báo cáo nó cho phía JS với mã 1006 và không có thông báo lý do. Trong các thử nghiệm của tôi, Chrome không bao giờ phản hồi các khung đóng do máy chủ khởi tạo (mã đóng 1000) cho thấy rằng mã 1006 có thể có nghĩa là Chrome đang báo lỗi nội bộ của chính nó.

PS Firefox v57.00 xử lý trường hợp này đúng cách và gửi thành công thông báo lý do của máy chủ cho phía JS.


2

Nghĩ rằng điều này có thể hữu ích cho những người khác. Biết regex là hữu ích, trẻ em. Ở trong trường.

Chỉnh sửa: Biến nó thành một chức năng tiện dụng!

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

Sử dụng:

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

Nguồn (với các chỉnh sửa nhỏ cho ngắn gọn): https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes


1

Tôi đã gặp lỗi khi sử dụng Chrome làm ứng dụng khách và golang gorilla websocket làm máy chủ dưới proxy nginx

Và chỉ gửi một số thông báo "ping" từ máy chủ đến máy khách sau mỗi x giây đã giải quyết được vấn đề


0

Đây có thể là URL websocket của bạn mà bạn đang sử dụng trên thiết bị không giống nhau (Bạn đang nhấn URL websocket khác từ android / iphonedevice)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.