Skip to content

Instantly share code, notes, and snippets.

@amcdnl
Created March 29, 2017 13:30
Show Gist options
  • Save amcdnl/36ea71dcb09033736637e1e6775f9d3e to your computer and use it in GitHub Desktop.
Save amcdnl/36ea71dcb09033736637e1e6775f9d3e to your computer and use it in GitHub Desktop.
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import * as io from 'socket.io-client';
@Injectable()
export class SocketService {
socket: any;
private host: string = `${window.location.protocol}//${window.location.hostname}:${window.location.port}`;
constructor() {
this.socket = io(this.host);
this.socket.on('error', (error: string) => {
throw new Error(`Sockets: ${error}`);
});
}
on(event: string): Observable<any> {
return new Observable((observer) => {
this.socket.on(event, (data) => {
observer.next(data);
});
});
}
emit(name, data): void {
this.socket.emit(name, data);
}
}
@itsJess1ca
Copy link

I use similar to this but store the observable for future returns so as to not generate excess listeners.
So far I've found it to be really reliable. Shutting down the listener on unsubscribes is a nice plus, too.

import { Injectable } from '@angular/core';
import Socket = SocketIOClient.Socket;
import { Observable } from 'rxjs';

@Injectable()
export class SocketManager {
  socket: Socket;
  connected: boolean = false;
  accepted: boolean = false;
  currentId: number;

  // Events
  events: Events = {};

  constructor() {
    this.socket = io(environment.socketUrl); // pulled from angular cli environment

    this.socket.on('error', (error: string) => {
      throw new Error(`Sockets: ${error}`);
    });
  }

  on(event: string) {
    const eventName = `${this.currentId}.${event}`;
    
    // Return early if the listener is already created
    if (this.events[eventName]) return this.events[eventName];

    // Otherwise, create a new observable and listener
    
    const observable = Observable.create((observer) => {
      this.socket.on(eventName, (data) => observer.next(data));

      // Return the function to call when unsubscribing
      return () => {
        this.socket.removeListener(eventName, (data) => observer.next(data));
        delete this.events[eventName];
      };
    });
    // bind to events object
    this.events[eventName] = observable;
    return observable;
  }

  emit(event: string, payload?: any) {
      payload ?
        this.socket.emit(event, payload) :
        this.socket.emit(event);
  }
}


export interface Events {
  [event: string]: Observable<any>;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment