Angular + Websocket


 

Angular使用RxJS,它本質上是一個反應式擴展的javascript實現。這是一個使用可觀察序列組成異步和基於事件的程序的庫,非常適合使用WebSockets。

簡而言之,RxJS允許我們從websocket連接中偵聽新消息,然后在“X”事件發生時執行操作。這方面的一個例子可以是實時聊天應用程序。假設我們有3個人連接到我們的聊天應用程序,其中一個人發送消息。如果我們想在收到消息時在應用程序中執行某些操作,那么我們可以簡單地訂閱“新消息”事件並在觸發事件時處理該事件。

使用WebSocket

在我們的角度應用程序中實現WebSockets的最佳方法是將我們的WebSockets和事件封裝在服務中,然后在我們希望與websocket交互的任何組件中調用該服務。

創建應用程序

使用Angular CLI,通過在命令行中鍵入以下內容來創建新應用程序:

ng new websocket_tutorial

這應該創建一個新的,功能齊全的Angular應用程序,我們將在其中實現基於websocket的服務。為了確保它的工作類型:

ng serve

您應該希望看到服務器在端口4200上成功啟動。如果您在首選的Web瀏覽器中導航到localhost:4200,您應該會看到'app works!' 在瀏覽器中顯示。現在我們已經啟動並運行了我們的基本應用程序,讓我們繼續創建我們的websocket服務。

創建我們的Websocket服務

為了讓我們開始,我們將創建一個非常簡單的服務,該服務將連接到任何給定的URL並返回我們可以在其他服務/組件中訂閱的RxJS主題,以便偵聽來自連接套接字的任何傳入消息。

ng g service websocket

我們需要從新服務頂部的rxjs庫中導入*。這將使我們能夠創造既能觀察又能觀察的主體。這實際上意味着我們的主題將觀察我們的websocket以獲取任何傳入消息,並將這些消息廣播到恰好訂閱此服務的任何組件。

 1 import { Injectable } from '@angular/core';
 2 import {Subject, Observer, Observable} from 'rxjs';;
 3 
 4 @Injectable()
 5 export class WebsocketService {
 6   constructor() { }
 7 
 8   private subject: Rx.Subject<MessageEvent>;
 9 
10   public connect(url): Rx.Subject<MessageEvent> {
11     if (!this.subject) {
12       this.subject = this.create(url);
13       console.log("Successfully connected: " + url);
14     } 
15     return this.subject;
16   }
17 
18   private create(url): Rx.Subject<MessageEvent> {
19     let ws = new WebSocket(url);
20 
21     let observable = Rx.Observable.create(
22     (obs: Rx.Observer<MessageEvent>) => {
23         ws.onmessage = obs.next.bind(obs);
24         ws.onerror = obs.error.bind(obs);
25         ws.onclose = obs.complete.bind(obs);
26         return ws.close.bind(ws);
27     })
28 let observer = {
29         next: (data: Object) => {
30             if (ws.readyState === WebSocket.OPEN) {
31                 ws.send(JSON.stringify(data));
32             }
33         }
34     }
35     return Rx.Subject.create(observer, observable);
36   }
37 
38 }

 

接下來我們要做的是創建一個與我們的websockets接口的第二個服務,它將作為一種適配器,它將我們的websocket的輸出調整為我們可以在前端輕松使用的形式。再次使用angular-cli創建此服務:

ng g service chat

這應該在根目錄中創建一個chat.service.ts。在這個文件中,我們想要做這樣的事情:

 1 import { Injectable } from '@angular/core';
 2 import { Observable, Subject } from 'rxjs';
 3 import { WebsocketService } from './websocket.service';
 4 
 5 const CHAT_URL = 'ws://echo.websocket.org/';
 6 
 7 export interface Message {
 8     author: string,
 9     message: string
10 }
11 
12 @Injectable()
13 export class ChatService {
14     public messages: Subject<Message>;
15 
16     constructor(wsService: WebsocketService) {
17         this.messages = <Subject<Message>>wsService
18             .connect(CHAT_URL)
19             .pipe(map((response: MessageEvent): Message => {
20                 let data = JSON.parse(response.data);
21                 return {
22                     author: data.author,
23                     message: data.message
24                 }
25             }));
26     }
27 }

 

如果是6.0以上的rxjs版本,map函數可以直接使用,代碼如下:

1 this.messages = <Subject<Message>>wsService
2             .connect(CHAT_URL)
3             .map((response: MessageEvent): Message => {
4                 let data = JSON.parse(response.data);
5                 return {
6                     author: data.author,
7                     message: data.message
8                 }
9             });

 

更新我們的應用組件

最后,我們要更新我們的app.component.ts文件,以便它導入我們新創建的聊天服務,並允許我們將消息推送到此websocket:

 1 import { Component } from '@angular/core';
 2 import { WebsocketService } from './websocket.service';
 3 import { ChatService } from './chat.service';
 4 
 5 @Component({
 6   selector: 'app-root',
 7   templateUrl: './app.component.html',
 8   styleUrls: ['./app.component.css'],
 9   providers: [ WebsocketService, ChatService ]
10 })
11 export class AppComponent {
12 
13     constructor(private chatService: ChatService) {
14         chatService.messages.subscribe(msg => {         
15             console.log("Response from websocket: " + msg);
16         });
17     }
18 
19     private message = {
20         author: 'tutorialedge',
21         message: 'this is a test message'
22     }
23 
24     sendMsg() {
25         console.log('new message from client to websocket: ', this.message);
26         this.chatService.messages.next(this.message);
27         this.message.message = '';
28     }
29 
30 }

 

最后,我們需要更新我們的app組件的html頁面,以便我們可以實際使用我們在組件文件中定義的sendMsg()函數:

<!-- app.component.html --> 
1 <h1>
2   Angular6 WebSocket 教程
3 </h1>
4 
5 <button (click)="sendMsg()">發送消息</button>

 

完成這些更改后,通過轉到根目錄並輸入以下命令來提供應用程序:

ng serve

您應該在瀏覽器中看到 "Angula6 WebSocket 教程" 和 “發送消息” 按鈕。

打開控制台並單擊按鈕幾次,您應該看到您的應用程序向測試websocket服務器發送和接收消息。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM