zoukankan      html  css  js  c++  java
  • 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服务器发送和接收消息。

     
  • 相关阅读:
    vue-cli webpack 全局引用jquery
    ELK日志框架(2):log4net.ElasticSearch+ Kibana实现日志记录和显示
    ELK日志框架(1):安装Elasticsearch组建单服务器多节点集群
    about-php
    Win7系统下,docker构建nginx+php7环境实践
    Windows7安装 docker-compose的过程
    Windows下docker的安装以及遇到的问题
    crontab的笔试题随想
    composer在update时提示file could not be downloaded: SSL operation failed with code 1. OpenSSL Error messages: error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO
    phpdocumentor 安装以及使用说明
  • 原文地址:https://www.cnblogs.com/zhenguo-chen/p/10441026.html
Copyright © 2011-2022 走看看