?
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测试数据plete.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测试数据ponent.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测试数据ponent.html' ,
8 styleUrls: ['./app测试数据ponent.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测试数据ponent.html -->
1 <h1> 2 Angular6 WebSocket 教程 3 </h1> 4 5 <button (click)="sendMsg()">发送消息</button>
?
完成这些更改后,通过转到根目录并输入以下命令来提供应用程序:
ng serve
您应该在浏览器中看到 "Angula6 WebSocket 教程" 和 “发送消息” 按钮。
打开控制台并单击按钮几次,您应该看到您的应用程序向测试websocket服务器发送和接收消息。
?
查看更多关于Angular + Websocket的详细内容...