Survey of whether Ably client libraries implement the guidance in the client library specification about how to handle different WebSocket close codes.
The spec defines how different RFC 6455 close codes should map to connection states:
Should trigger disconnected/suspended (retryable):
GOING_AWAY(1001)ABNORMAL_CLOSE(1006)
Should trigger failed (terminal):
CLOSE_PROTOCOL_ERROR(1002) — reason code 80000REFUSE(1003) — reason code 0100NO_UTF8(1007) — reason code 80000POLICY_VALIDATION(1008) — reason code 0100TOOBIG(1009) — reason code 40000EXTENSION(1010) — reason code 80000UNEXPECTED_CONDITION(1011) — reason code 80000TLS_ERROR(1015) — reason code 80000
| SDK | Commit | Details |
|---|---|---|
| ably-java | 16f03d1 |
Comprehensive switch statement in WebSocketTransport.java (lines 310–347). Defines all close code constants (lines 31–43). Maps codes to disconnected, refused, too-big, or failed states. |
| ably-cocoa | 14d2661 |
Comprehensive switch statement in ARTWebSocketTransport.m (lines 278–325). Defines close code enum (lines 24–37). Same state mapping as Java. |
| SDK | Commit | Details |
|---|---|---|
| ably-flutter | 6a93ac5 |
Delegates to ably-java (Android) and ably-cocoa (iOS). No close code logic in the Flutter layer itself — state changes are passed through from the native SDKs. |
| SDK | Commit | Details |
|---|---|---|
| ably-js | 9ec7737 |
Only checks for code 1000 (clean close). All other codes produce a generic disconnected state with error 80003. No constants, enums, or mappings for other close codes. See websockettransport.ts lines 163–187. |
| ably-dotnet | f8a6f89 |
Logs the close status via ClientWebSocket.CloseStatus but treats all closures generically. No conditional logic based on specific close codes. See MsWebSocketConnection.cs lines 187–203. |
| ably-go | 17f5d49 |
All WebSocket errors treated uniformly. Close codes are not extracted or examined. The recoverable() function only checks Ably error codes (40000–49999 range), not WebSocket close codes. See realtime_conn.go. |
| ably-python | 324a9f6 |
Distinguishes ConnectionClosedOK (code 1000) from generic WebSocketException. No code-specific handling — all non-1000 closures trigger generic retry logic. See websockettransport.py. |
| ably-ruby | b303a8e |
Close code is captured as a log string ("#{event.code}: #{event.reason}") but never used for conditional logic. All closures transition to disconnected with retry. See websocket_transport.rb lines 240–242. |
| SDK | Commit | Notes |
|---|---|---|
| ably-rust | d62743f |
REST-only client; no realtime/WebSocket functionality. |
| ably-php | ebc27a9 |
REST-only client; no realtime/WebSocket functionality. |
ably-swift was not included in this survey.
In the 5 non-compliant realtime SDKs, close codes that the spec says should trigger a
failed (terminal) state — such as 1002 (CLOSE_PROTOCOL_ERROR), 1007 (NO_UTF8),
1010 (EXTENSION), 1011 (UNEXPECTED_CONDITION), and 1015 (TLS_ERROR) — will instead
trigger reconnection attempts. This means the client will keep retrying a connection that
the server has indicated is fundamentally broken.