aleks Koptev
aleks Koptev

Reputation: 61

Close the Websocket connection when tab closes

I have an Angular with ng2-stompjs and socksjs client and Spring boot Websocket server. What I want to do, is disconnect from Websocket when a current browser tab is closed.

@Component({
selector: 'app-test-list',
templateUrl: './test-list.component.html',
styleUrls: ['./test-list.component.css']
})
export class TestListComponent implements OnInit, OnDestroy {
// Stream of messages
private subscription: Subscription;
public messages: Observable<Message>;

// Subscription status
public subscribed: boolean;

// Array of historic message (bodies)
public mq: Array<string> = [];

// A count of messages received
public count = 0;

private _counter = 1;


constructor(private _stompService: StompService) {
}

sendMessage() {
this._stompService.publish('/app/hello', 'My important message');
}

Tried to disconnect 'OnDestroy', but it doesn't help

ngOnDestroy(): void {
this.sendMessage();
this.unsubscribe()
}

Tried to subscribe to a connectionState and check on connection status enum, but it doesn't work either.

ngOnInit(): void {
this.subscribed = false
this.subscribe();
this._stompService.connectionState$.subscribe(next => {
  console.log('Connection State', RxStompState[next]);
  if(next === RxStompState.CLOSING) {
    this.unsubscribe()
  }
 });
 }


public subscribe() {
if (this.subscribed) {
  return;
}

// Stream of messages
this.messages = this._stompService.subscribe('/topic/hi');

// Subscribe a function to be run on_next message
this.subscription = this.messages.subscribe(this.on_next);

this.subscribed = true;

}


public unsubscribe() {
if (!this.subscribed) {
  return;
 }

// This will internally unsubscribe from Stomp Broker
// There are two subscriptions - one created explicitly, the other created in the 
 template by use of 'async'
this.subscription.unsubscribe();
// this._stompService.disconnect();
this.subscription = null;
this.messages = null;

this.subscribed = false;
}


public onSendMessage() {
const _getRandomInt = (min, max) => {
  return Math.floor(Math.random() * (max - min + 1)) + min;
 };
this._stompService.publish('/topic/ng-demo-sub',
  `{ type: "Test Message", data: [ ${this._counter}, ${_getRandomInt(1, 100)}, 
 ${_getRandomInt(1, 100)}] }`);

this._counter++;
}


 /** Consume a message from the _stompService */
 public on_next = (message: Message) => {

 // Store message in "historic messages" queue
 this.mq.push(message.body + '\n');

 // Count it
 this.count++;

 // Log it to the console
 console.log(message);
}

}

At this point, I'm stuck and run out of ideas. I would appreciate it if you could give your advice! Thanks in advance.

Upvotes: 0

Views: 2033

Answers (1)

aleks Koptev
aleks Koptev

Reputation: 61

The approach, recommended by Victor_figm works perfectly fine for me. Just listening to 'beforeunload' event and unsubscribing. That's the solution:

@HostListener('window:beforeunload', ['$event'])
async onBeforeUnload(): Promise<void> {
  this.unsubscribe();
}

Upvotes: 2

Related Questions