feat: The chatroom-components listens to the SSE-stream of the chatroom
authorKai Moritz <kai@juplo.de>
Sun, 25 Dec 2022 23:08:25 +0000 (00:08 +0100)
committerKai Moritz <kai@juplo.de>
Sat, 7 Jan 2023 12:22:41 +0000 (13:22 +0100)
src/app/chatroom.service.ts
src/app/chatroom/chatroom.component.html
src/app/chatroom/chatroom.component.ts
src/app/message.ts [new file with mode: 0644]

index ab92206..f7958fa 100644 (file)
@@ -1,7 +1,8 @@
 import { Injectable } from '@angular/core';
 import { HttpClient } from "@angular/common/http";
-import { Observable, of } from "rxjs";
+import { Observable } from "rxjs";
 import { Chatroom } from "./chatroom";
+import { Message } from "./message";
 
 @Injectable({
   providedIn: 'root'
@@ -10,6 +11,7 @@ export class ChatroomService {
 
   private uriList = 'http://localhost:8080/list';
   private uriGet = 'http://localhost:8080/get/';
+  private uriListen = 'http://localhost:8080/listen/';
 
   constructor(private http: HttpClient) { }
 
@@ -20,4 +22,29 @@ export class ChatroomService {
   getChatroom(id: String): Observable<Chatroom> {
     return this.http.get<Chatroom>(this.uriGet + id);
   }
+
+  listen(id: String): Observable<Message> {
+    return new Observable<Message>((observer) => {
+      let url = this.uriListen + id;
+      let eventSource = new EventSource(url);
+      eventSource.onmessage = (event) => {
+        console.debug('Received event: ', event);
+        let message: Message = JSON.parse(event.data);
+        observer.next(message);
+      };
+      eventSource.onerror = (error) => {
+        // readyState === 0 (closed) means the remote source closed the connection,
+        // so we can safely treat it as a normal situation. Another way
+        // of detecting the end of the stream is to insert a special element
+        // in the stream of events, which the client can identify as the last one.
+        if(eventSource.readyState === 0) {
+          console.log('The stream has been closed by the server.');
+          eventSource.close();
+          observer.complete();
+        } else {
+          observer.error('EventSource error: ' + error);
+        }
+      }
+    });
+  }
 }
index a45ee7b..2b3a709 100644 (file)
@@ -3,5 +3,11 @@
     <h3 class="panel-title">{{chatroom.name}}</h3>
   </div>
   <div class="panel-body">
+    <ul>
+      <li class="input-group" *ngFor="let message of messages">
+        <span class="input-group-addon">{{message.user}}</span>
+        <span class="form-control">{{message.text}}</span>
+      </li>
+    </ul>
   </div>
 </div>
index 51aff66..a25b09c 100644 (file)
@@ -1,8 +1,9 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, OnInit, NgZone } from '@angular/core';
 import { ActivatedRoute } from '@angular/router';
 import { ChatroomService } from "../chatroom.service";
 import { UserService } from "../user.service";
 import { Chatroom } from "../chatroom";
+import { Message } from "../message";
 
 @Component({
   selector: 'app-chatroom',
@@ -12,11 +13,13 @@ import { Chatroom } from "../chatroom";
 export class ChatroomComponent implements OnInit {
 
   chatroom: Chatroom = { id: 'FOO', name: 'BAR'};
+  messages: Message[] = [];
 
   constructor(
     private chatroomsService: ChatroomService,
     private userService: UserService,
-    private route: ActivatedRoute) {}
+    private route: ActivatedRoute,
+    private zone: NgZone) {}
 
   ngOnInit(): void
   {
@@ -32,6 +35,11 @@ export class ChatroomComponent implements OnInit {
       this.chatroomsService
         .getChatroom(id)
         .subscribe(chatroom => this.chatroom = chatroom);
+      this.chatroomsService
+        .listen(id)
+        .subscribe({
+          next: message => this.zone.run(() => this.messages.push(message)),
+          error: err => console.error('something wrong occurred: ' + err) });
     }
   }
 }
diff --git a/src/app/message.ts b/src/app/message.ts
new file mode 100644 (file)
index 0000000..f5451a6
--- /dev/null
@@ -0,0 +1,8 @@
+export interface Message
+{
+  id: string,
+  serialNumber: number,
+  timestamp: string,
+  user: string,
+  text: string,
+}