title: Angular 4 RxJs WebSocket
body: <p>I'm trying to understand how to work with angular 4 and websockets. In my older projects with angularjs (1.x) I followed this guide:
  <a href="http://clintberry.com/2013/angular-js-websocket-service/" rel="nofollow noreferrer">AngularJs Websocket Service</a></p>
  
  <p>The solution in this guide is to store a Promise and an Id for each request inside a collection, so when the server sends back a response with this id, I can retrieve the right Promise from the collection and choose to use "notify" if I expect more messages, and "resolve" if is a one shot request-response.</p>
  
  <p>In Angular 4 is preferable to work with RxJs Observable / Subject. A basic use of websocket can be found in this post: <a href="https://tutorialedge.net/post/typescript/angular/angular-websockets-tutorial/" rel="nofollow noreferrer">Angular (2+) Websockets Tutorial</a>.
  But how can I achieve an equivalent mechanism from the first post with RxJs?</p>
  
  <p>This is my starting point Service, it is a simple echo client:</p>
  
  <pre><code>import { Injectable } from '@angular/core';
  import { Observable, Subject } from 'rxjs/Rx';
  import * as Rx from 'rxjs/Rx';
  
  @Injectable()
  export class WebsocketService {
  
      private socketUrl: any = 'wss://echo.websocket.org';
      private subject: Rx.Subject&lt;MessageEvent&gt;;    
      private ws : any;
      public messages: Subject&lt;any&gt;;
  
      constructor() {
          this.messages = &lt;Subject&lt;any&gt;&gt;this.connect()
            .map((response: MessageEvent): any =&gt; {
                let data = JSON.parse(response.data);
                return data;
            });
      }
  
    connect() : Rx.Subject&lt;MessageEvent&gt; {
      if (!this.subject) {
        this.subject = this.create(this.socketUrl);
        console.log("Successfully connected: " + this.socketUrl);
      } 
      return this.subject;
    }
  
    private create(url): Rx.Subject&lt;MessageEvent&gt; {
      this.ws = new WebSocket(url);
  
      let observable = Rx.Observable.create(
      (obs: Rx.Observer&lt;MessageEvent&gt;) =&gt; {
          this.ws.onmessage = obs.next.bind(obs);
          this.ws.onerror = obs.error.bind(obs);
          this.ws.onclose = obs.complete.bind(obs);
          return this.ws.close.bind(this.ws);
      })
      let observer = {
          next: (data: Object) =&gt; {
              if (this.ws.readyState === WebSocket.OPEN) {
                  this.ws.send(JSON.stringify(data));
              }
          }
      }
      return Rx.Subject.create(observer, observable);
    }
  
  }
  </code></pre>