angularwebsocketstomp

ensuring STOMP socket connection is established before subscribing


In my Angular 2 project, I am using the ng2-stomp-service to establish a socket connection to the server.

Most of the time it works fine, but sometimes I get this error when trying to subscribe to the socket, saying that my connection has not been established yet:

Error: Uncaught (in promise): Error: InvalidStateError: The connection has not been established yet Error: InvalidStateError: The connection has not been established yet
    at SockJS.send (main.js:158)
    at Client._transmit (stomp.js:159)
    at Client.subscribe (stomp.js:379)
    at StompService.subscribe (stomp.service.ts:132)
    at slide-manager.service.ts:129
    at ZoneDelegate.invoke (zone.js:391)
    at Object.onInvoke (core.es5.js:3933)
    at ZoneDelegate.invoke (zone.js:390)
    at Zone.run (zone.js:141)
    at zone.js:818
    at SockJS.send (main.js:158)
    at Client._transmit (stomp.js:159)
    at Client.subscribe (stomp.js:379)
    at StompService.subscribe (stomp.service.ts:132)
    at slide-manager.service.ts:129
    at ZoneDelegate.invoke (zone.js:391)
    at Object.onInvoke (core.es5.js:3933)
    at ZoneDelegate.invoke (zone.js:390)
    at Zone.run (zone.js:141)
    at zone.js:818
    at resolvePromise (zone.js:770)
    at zone.js:821
    at ZoneDelegate.invokeTask (zone.js:424)
    at Object.onInvokeTask (core.es5.js:3924)
    at ZoneDelegate.invokeTask (zone.js:423)
    at Zone.runTask (zone.js:191)
    at drainMicroTaskQueue (zone.js:584)
    at WebSocket.ZoneTask.invoke (zone.js:490)

The piece of this stack trace that belongs to me is the slide-manager.service.ts:129. That code is at the stomp.subscribe line of this code:

this.socketConfig = {
      host: 'http://' + getHost() + '/app-ws',
      debug: true,
      queue: {'init': false}
    };   

 this.stomp.configure(this.socketConfig);
 this.stomp.startConnect().then((frame) => {
 this.stomp.done('init');
 this.connected = true;
 this.spectraSubscription = this.stomp.subscribe('/topic/spectra', (spectra) => {
     if (spectra && (!this.theChart || hostElement.childElementCount === 0) && !this.refreshFlag) {
         this.makeChart(spectra.points, hostElement);
         this.refreshFlag = true;
     } else if (spectra && (this.theChart || hostElement.childElementCount > 0) || this.refreshFlag) {
         this.theChart.collectionView.sourceCollection = spectra.points;
         this.theChart.collectionView.refresh();
     }
  });

How can I ensure that the connection is indeed established before it tries to execute the .subscribe()? I figured putting it in the .then() block would do the trick, since that should only be executed after the connection's promise has resolved, but apparently it's still getting triggered even when no connection exists (according to the error).

Or is there more at play here that I'm missing?


Solution

  • I was able to resolve this issue by checking the built-in "status" property of the stomp client:

    if (this.stomp.status === 'CONNECTED') {
        // do stuff that requires a connection, like establish subscriptions
    }