From 0b6996b700f4147dbad5f793158a01d469ed0b19 Mon Sep 17 00:00:00 2001 From: Sean Engelhardt Date: Thu, 28 Jun 2018 17:11:04 +0200 Subject: [PATCH] Add WebSockets using rxjs/webSocket, autoupdate example --- client/proxy.conf.json | 5 +++ client/src/app/app.module.ts | 3 +- client/src/app/core/services/auth.service.ts | 2 +- .../core/services/websocket.service.spec.ts | 15 +++++++ .../app/core/services/websocket.service.ts | 43 +++++++++++++++++++ client/src/app/site/site.component.ts | 17 ++++++++ 6 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 client/src/app/core/services/websocket.service.spec.ts create mode 100644 client/src/app/core/services/websocket.service.ts diff --git a/client/proxy.conf.json b/client/proxy.conf.json index bac003d55..a5180e715 100644 --- a/client/proxy.conf.json +++ b/client/proxy.conf.json @@ -14,5 +14,10 @@ "/rest": { "target": "http://localhost:8000", "secure": false + }, + "/ws/site": { + "target": "ws://localhost:8000", + "secure": false, + "ws": true } } diff --git a/client/src/app/app.module.ts b/client/src/app/app.module.ts index 5aaf17511..79b7fadb5 100644 --- a/client/src/app/app.module.ts +++ b/client/src/app/app.module.ts @@ -36,6 +36,7 @@ import { SiteComponent } from './site/site.component'; import { StartComponent } from './site/start/start.component'; import { ToastComponent } from './core/directives/toast/toast.component'; import { ToastService } from './core/services/toast.service'; +import { WebsocketService } from './core/services/websocket.service'; import { ProjectorContainerComponent } from './projector-container/projector-container.component'; import { AlertComponent } from './core/directives/alert/alert.component'; @@ -79,7 +80,7 @@ library.add(fas); FontAwesomeModule, AppRoutingModule ], - providers: [Title, ToastService], + providers: [Title, ToastService, WebsocketService], bootstrap: [AppComponent] }) export class AppModule {} diff --git a/client/src/app/core/services/auth.service.ts b/client/src/app/core/services/auth.service.ts index 2e4eee5c3..73508fc82 100644 --- a/client/src/app/core/services/auth.service.ts +++ b/client/src/app/core/services/auth.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { HttpClient, HttpResponse, HttpErrorResponse, HttpHeaders } from '@angular/common/http'; import { Observable, of, throwError } from 'rxjs'; -import { catchError, map, tap } from 'rxjs/operators'; +import { catchError, tap } from 'rxjs/operators'; import { User } from 'app/core/models/user'; diff --git a/client/src/app/core/services/websocket.service.spec.ts b/client/src/app/core/services/websocket.service.spec.ts new file mode 100644 index 000000000..81030cd29 --- /dev/null +++ b/client/src/app/core/services/websocket.service.spec.ts @@ -0,0 +1,15 @@ +import { TestBed, inject } from '@angular/core/testing'; + +import { WebsocketService } from './websocket.service'; + +describe('WebsocketService', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [WebsocketService] + }); + }); + + it('should be created', inject([WebsocketService], (service: WebsocketService) => { + expect(service).toBeTruthy(); + })); +}); diff --git a/client/src/app/core/services/websocket.service.ts b/client/src/app/core/services/websocket.service.ts new file mode 100644 index 000000000..b884e22b9 --- /dev/null +++ b/client/src/app/core/services/websocket.service.ts @@ -0,0 +1,43 @@ +import { Injectable } from '@angular/core'; +import { Router } from '@angular/router'; +import { webSocket, WebSocketSubject } from 'rxjs/webSocket'; + +@Injectable({ + providedIn: 'root' +}) +export class WebsocketService { + constructor(private router: Router) {} + + //might be any for simplicity or MessageEvent or something different + private subject: WebSocketSubject; + + public connect(): WebSocketSubject { + const socketProtocol = this.getWebSocketProtocoll(); + const socketPath = this.getWebSocketPath(); + const socketServer = window.location.hostname + ':' + window.location.port; + if (!this.subject) { + this.subject = webSocket(socketProtocol + socketServer + socketPath); + } + return this.subject; + } + + // delegates to websockets for either the side or projector websocket + private getWebSocketPath(): string { + //currentRoute does not end with '/' + const currentRoute = this.router.url; + if (currentRoute.includes('/projector') || currentRoute.includes('/real-projector')) { + return '/ws/projector'; + } else { + return '/ws/site/'; + } + } + + // returns the websocket protocoll + private getWebSocketProtocoll(): string { + if (location.protocol === 'https') { + return 'wss://'; + } else { + return 'ws://'; + } + } +} diff --git a/client/src/app/site/site.component.ts b/client/src/app/site/site.component.ts index 19de5c42b..466235a61 100644 --- a/client/src/app/site/site.component.ts +++ b/client/src/app/site/site.component.ts @@ -3,6 +3,9 @@ import { Router } from '@angular/router'; import { BreakpointObserver, Breakpoints, BreakpointState } from '@angular/cdk/layout'; import { AuthService } from 'app/core/services/auth.service'; +import { WebsocketService } from 'app/core/services/websocket.service'; +import { Subject } from 'rxjs'; +import { tap } from 'rxjs/operators'; @Component({ selector: 'app-site', @@ -14,6 +17,7 @@ export class SiteComponent implements OnInit { constructor( private authService: AuthService, + private websocketService: WebsocketService, private router: Router, private breakpointObserver: BreakpointObserver ) {} @@ -28,6 +32,19 @@ export class SiteComponent implements OnInit { this.isMobile = false; } }); + + // connect to a the websocket + const socket = this.websocketService.connect(); + + // subscribe to the socket + socket.subscribe(response => { + console.log('log : ', response); // will contain all the config variables + }); + + // basically everything needed for AutoUpdate + socket.next(val => { + console.log('socket.next: ', val); + }); } logOutButton() {