好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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

 

查看更多关于Angular + Websocket的详细内容...

  阅读:41次