微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Angular 8+是否有更好的方法来进行此Websocket服务?

如何解决Angular 8+是否有更好的方法来进行此Websocket服务?

我需要提供websocket服务,如果连接关闭,它将适应消息并重新连接。 我做了这个实现,但是有些事情有些奇怪,或者我只是不明白它应该如何正常工作。 这是WebSocketService:

import { Injectable,OnDestroy,Inject } from '@angular/core';
import { Observable,SubscriptionLike,Subject,Observer,interval } from 'rxjs';
import { filter,map } from 'rxjs/operators';
import { WebSocketSubject,WebSocketSubjectConfig } from 'rxjs/webSocket';
import { share,distinctUntilChanged,takeWhile } from 'rxjs/operators';
import { IWebsocketService,IWsMessage,WebSocketConfig } from './websocket.interfaces';
import { config } from './websocket.config';

@Injectable({
    providedIn: 'root'
})
export class WebSocketService implements IWebsocketService,OnDestroy {

    private config: WebSocketSubjectConfig<IWsMessage<any>>;

    private websocketSub: SubscriptionLike;
    private statusSub: SubscriptionLike;

    private reconnection$: Observable<number>;
    private websocket$: WebSocketSubject<IWsMessage<any>>;
    private connection$: Observer<boolean>;
    public wsMessages$: Subject<IWsMessage<any>>;

    private reconnectInterval: number;
    private reconnectAttempts: number;
    private isConnected: boolean;

    public status: Observable<boolean>;

    constructor(@Inject(config) private wsConfig: WebSocketConfig) {
        console.log('[WebSocketService] constructor');
        this.wsMessages$ = new Subject<IWsMessage<any>>();

        this.reconnectInterval = wsConfig.reconnectInterval || 2000; // pause between connections
        this.reconnectAttempts = wsConfig.reconnectAttempts || 10; // number of connection attempts

        this.config = {
            url: wsConfig.url,cloSEObserver: {
                next: (event: CloseEvent) => {
                    console.log('[WebSocketService] WebSocket closed!');
                    this.websocket$ = null;
                    this.connection$.next(false);
                    this.isConnected = false;
                }
            },openObserver: {
                next: (event: Event) => {
                    console.log('[WebSocketService] WebSocket connected!');
                    this.connection$.next(true);
                    this.isConnected = true;
                }
            }
        };

        // connection status
        this.status = new Observable<boolean>((observer) => {
            this.connection$ = observer;
        }).pipe(share(),distinctUntilChanged());

        // run reconnect if not connection
        this.statusSub = this.status
            .subscribe((isConnected) => {
                this.isConnected = isConnected;

                if (!this.reconnection$ && typeof(isConnected) === 'boolean' && !isConnected) {
                    this.reconnect();
                }
            });

        this.websocketSub = this.wsMessages$.subscribe(
            null,(error: ErrorEvent) => console.error('WebSocket error!',error)
        );

        this.connect();
    }

    ngOnDestroy() {
        this.websocketSub.unsubscribe();
        this.statusSub.unsubscribe();
    }

    /*
    * connect to WebSocked
    * */
    public connect(): void {
        this.websocket$ = new WebSocketSubject(this.config);

        this.websocket$.subscribe(
            (message) => this.wsMessages$.next(message),(error: Event) => {
                if (!this.websocket$) {
                    // run reconnect if errors
                    this.reconnect();
                }
            });
    }

    /*
    * reconnect if not connecting or errors
    * */
    private reconnect(): void {
        this.reconnection$ = interval(this.reconnectInterval)
            .pipe(takeWhile((v,index) => index < this.reconnectAttempts && !this.websocket$));

        this.reconnection$.subscribe(
            () => this.connect(),null,() => {
                // Subject complete if reconnect attemts ending
                this.reconnection$ = null;

                if (!this.websocket$) {
                    this.wsMessages$.complete();
                    this.connection$.complete();
                }
            });
    }

    /*
    * on message event
    * */
    public on<T>(eventId: any): Observable<T> {
        console.log(eventId);
        if (eventId) {
            return this.wsMessages$.pipe(
                filter((message: IWsMessage<T>) => message.id === eventId),map((message: IWsMessage<T>) => message.result ? message.result : message.error)
            );
        }
    }

    /*
    * on message to server
    * */
    public send(eventId: any,data: any = {}): void {
        let that = this;
        if (eventId && this.isConnected && this.websocket$) {
            data['id'] = eventId;
            this.websocket$.next(data);
        } else {
            setTimeout(function() {
                that.send(eventId,data);
            },500);
            console.log('Still connecting,resending messsage...');
        }
    }
}

一个问题是,我很少在Chrome中看到此错误

WebSocket connection to '...' Failed: Invalid frame header 

在Firefox中:

The connection to '...' was interrupted while the page was loading.

我真的不明白发生这种情况的原因和时间,因为我说这种情况很少发生。

我也很担心连接关闭的速度以及它是否应该这么快:连接后大约20秒后关闭,然后重新连接。然后像这样循环。 我不确定我的reconnectAttempts和reconnectInterval是否正在做任何事情...

很高兴获得任何帮助!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。