Skip to content

WebSocket Errors Are Not Properly Handled in Safari Leading to Random Disconnects #58336

@Olga-Maltseva

Description

@Olga-Maltseva

Background and Motivation
When using the @microsoft/signalr library with WebSocket transport in Safari, the connection randomly disconnects after 15-20 minutes of inactivity when the user switches tabs or stops interacting with the browser. This behavior is inconsistent with other browsers (e.g., Chrome, Firefox), where the connection remains stable under similar conditions.

Upon investigation, I found that the WebSocket error handler in the library (webSocket.onerror) logs errors at the Information level and provides minimal information about the issue, making it difficult to identify the root cause. Furthermore, the library does not provide detailed error-handling logic to manage such WebSocket errors effectively or to implement custom reconnection strategies when these errors occur.

Steps to Reproduce

  • Set up a SignalR connection using the @microsoft/signalr library with WebSocket transport.
  • Use the Safari browser and open a page that connects via SignalR.
  • Switch tabs or leave the browser inactive for 15-20 minutes.
  • Observe that the connection gets closed without detailed error information.

Environment

  • Library version: @microsoft/signalr version 6.0.25
  • Browser: Safari (Version 17.6)
  • OS: macOS (Version 14.6.1)

Proposed Solution

  • Improve the logging mechanism for WebSocket errors by including more details (e.g., WebSocket status, error type) and logging at a higher severity level (e.g., Error).
  • Expose the internal WebSocket instance or provide a way to attach custom event handlers (onerror, onclose) for better control over connection management.
  • Review the reconnection strategy in scenarios where Safari or other browsers close the WebSocket due to inactivity or tab suspension.

Proposed API
Expected Behavior

  • The library should provide more detailed error logging and allow users to access the internal WebSocket instance to add custom error handling.
  • Errors should be logged at a higher level (e.g., Error) to make them visible and actionable.
  • A mechanism should be available to manage WebSocket errors more robustly, particularly in browsers known for connection stability issues.

Actual Behavior

webSocket.onerror = (event: Event) => {
    let error: any = null;
    // ErrorEvent is a browser-only type; we need to check if the type exists before using it
    if (typeof ErrorEvent !== "undefined" && event instanceof ErrorEvent) {
        error = event.error;
    } else {
        error = "There was an error with the transport";
    }
    this._logger.log(LogLevel.Information, `(WebSockets transport) ${error}.`);
};

There is no built-in support for custom error handling for WebSocket errors, making it difficult to implement a solution that works across different browsers.

Usage Examples

import { HubConnectionBuilder, LogLevel, HttpTransportType } from "@microsoft/signalr";

// Custom error handler
function handleWebSocketError(error) {
    console.error("Custom WebSocket error handler:", error);
    // Custom logic to handle errors, such as reconnecting or logging details
}

// Custom reconnection handler
function handleReconnection(attempt) {
    console.log(`Reconnection attempt #${attempt}`);
    // Custom logic for reconnection attempts, such as increasing delay intervals
}

// Create the connection
const connection = new HubConnectionBuilder()
    .withUrl("/hub", {
        transport: HttpTransportType.WebSockets,
        errorHandler: handleWebSocketError, // Using the new error handler option
        reconnectionHandler: handleReconnection, // Using the new reconnection handler option
    })
    .configureLogging(LogLevel.Information)
    .withAutomaticReconnect()
    .build();

// Start the connection
connection.start().then(() => {
    console.log("Connection started!");
}).catch((err) => {
    console.error("Failed to start connection:", err);
});

Thank you for considering this issue!

Metadata

Metadata

Assignees

No one assigned

    Labels

    api-suggestionEarly API idea and discussion, it is NOT ready for implementationarea-signalrIncludes: SignalR clients and servers

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions