Angular + Websocket

 

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

簡而言之,RxJS容許咱們從websocket鏈接中偵聽新消息,而後在「X」事件發生時執行操做。這方面的一個例子能夠是實時聊天應用程序。假設咱們有3我的鏈接到咱們的聊天應用程序,其中一我的發送消息。若是咱們想在收到消息時在應用程序中執行某些操做,那麼咱們能夠簡單地訂閱「新消息」事件並在觸發事件時處理該事件。css

使用WebSocket

在咱們的角度應用程序中實現WebSockets的最佳方法是將咱們的WebSockets和事件封裝在服務中,而後在咱們但願與websocket交互的任何組件中調用該服務。html

建立應用程序

使用Angular CLI,經過在命令行中鍵入如下內容來建立新應用程序:前端

ng new websocket_tutorial

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

ng serve

您應該但願看到服務器在端口4200上成功啓動。若是您在首選的Web瀏覽器中導航到localhost:4200,您應該會看到'app works!' 在瀏覽器中顯示。如今咱們已經啓動並運行了咱們的基本應用程序,讓咱們繼續建立咱們的websocket服務。web

建立咱們的Websocket服務

爲了讓咱們開始,咱們將建立一個很是簡單的服務,該服務將鏈接到任何給定的URL並返回咱們能夠在其餘服務/組件中訂閱的RxJS主題,以便偵聽來自鏈接套接字的任何傳入消息。瀏覽器

ng g service websocket

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

 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。在這個文件中,咱們想要作這樣的事情:websocket

 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服務器發送和接收消息。

相關文章
相關標籤/搜索