Skip to content

WebSocketSubject does not provide code on close #7353

Open
@ncowama

Description

@ncowama

Describe the bug

When closing the socket as part of subscription teardown, the implementation calls _socket.close():

https://github.com/ReactiveX/rxjs/blob/7.8.1/src/internal/observable/dom/WebSocketSubject.ts#L380-L382

Because there is no status code, WebSocket defaults to status code 1005 - No Status Rcvd ("Indicates that no status code was provided even though one was expected."). Given that the close is expected, the status should be 1000 - Normal Closure. Otherwise the consumer might treat status other than 1000 as error state, which is incorrect.


There is a related issue: #4087 with a proposed solution to call .error({ code }).

It's possible to work around this with a side-effect calling wsSubject.error({ code: 1000 }), but it's not ideal

disabled
  .pipe(
    tap({
      next: (disabled) => {
        if (disabled) {
          wsSubject.error({ code: 1000 });
        }
      },
    }),
    switchMap((disabled) => iif(() => !disabled, ws, EMPTY))
  )

Expected behavior

socket is closed with code=1000 when subscription is closed. Or a mechanism to define status code for the socket.close call.

Reproduction code

import { BehaviorSubject, EMPTY, iif, retry, switchMap } from 'rxjs';
import { webSocket } from 'rxjs/webSocket';

const disabled = new BehaviorSubject(false);
const wsSubject = webSocket({
  url: 'wss://socketsbay.com/wss/v2/1/demo/',
  openObserver: {
    next: () => console.log('Open'),
  },
  closeObserver: {
    next: (event) => console.log(`Closed, code=${event.code}`),
  },
});
const ws = wsSubject.pipe(retry({ count: 3, delay: 500 }));

disabled
  .pipe(switchMap((disabled) => iif(() => !disabled, ws, EMPTY)))
  .subscribe((value) => console.log(value));

setTimeout(() => {
  console.log('disabled=true');
  disabled.next(true);
}, 1000);

setTimeout(() => {
  console.log('disabled=false');
  disabled.next(false);
}, 2000);

// Output:
// Open
// disabled=true
// Closed, code=1005
// disabled=false
// Open

Reproduction URL

https://stackblitz.com/edit/rxjs-i5b8xv?file=index.ts

Version

v7.8.1

Environment

No response

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions