異なるバックエンドサービスに接続するために、異なるエンドポイントwebsocket URLを使用する必要がある典型的な使用例があります。角2:作成前にサービス設定を渡すには?
がimport {Injectable} from "@angular/core";
import {Subject} from "rxjs/subject";
import {Observable} from "rxjs/observable";
import {WebSocketSubject, WebSocketSubjectConfig} from "rxjs/observable/dom/WebSocketSubject";
import {Observer} from "rxjs/observer";
@Injectable()
export class WebSocketService<T> extends Subject<T> {
private reconnectionObservable: Observable<number>;
private wsSubjectConfig: WebSocketSubjectConfig;
private socket: WebSocketSubject<any>;
private connectionObserver: Observer<boolean>;
public connectionStatus: Observable<boolean>;
constructor(private config: WebServiceConfig) {
super();
// connection status
this.connectionStatus = new Observable((observer) => {
this.connectionObserver = observer;
}).share().distinctUntilChanged();
// config for WebSocketSubject
// except the url, here is closeObserver and openObserver to update connection status
this.wsSubjectConfig = {
url: config.URL,
closeObserver: {
next: (e:CloseEvent) => {
this.socket = null;
this.connectionObserver.next(false);
}
},
openObserver: {
next: (e:Event) => {
this.connectionObserver.next(true);
}
}
};
this.connect();
// we follow the connection status and run the reconnect while losing the connection
this.connectionStatus.subscribe((isConnected) => {
if (!this.reconnectionObservable && typeof(isConnected) == "boolean" && !isConnected) {
this.reconnect();
}
});
}
connect():void {
this.socket = new WebSocketSubject(this.wsSubjectConfig);
this.socket.subscribe(
(m) => {
this.next(m); // when receiving a message, we just send it to our Subject
},
(error:Event) => {
if (!this.socket) {
// in case of an error with a loss of connection, we restore it
this.reconnect();
}
});
}
reconnect():void {
this.reconnectionObservable = Observable.interval(this.config.getRetryInterval())
.takeWhile((v, index) => {
return index < this.config.attempts && !this.socket
});
this.reconnectionObservable.subscribe(
() => {
this.connect();
},
null,
() => {
// if the reconnection attempts are failed, then we call complete of our Subject and status
this.reconnectionObservable = null;
if (!this.socket) {
this.complete();
this.connectionObserver.complete();
}
});
}
send(data:any):void {
this.socket.next(this.config.serializer(data));
}
}
export enum TimeUnits {
SECONDS = 1000,
MINUTES = SECONDS * 60,
HOURS = MINUTES * 60,
DAYS = HOURS * 24
}
export class WebServiceConfig {
URL: string = 'ws://localhost:4242/ws';
attempts: number = 10; /// number of connection attempts
retryUnit: TimeUnits = TimeUnits.SECONDS; /// pause between connections
retryInterval: number = 5;
serializer: (data: any) => any = function (data: any) {
return JSON.stringify(data);
};
deserializer: (e: MessageEvent) => any = function (e: MessageEvent) {
return e;
};
getRetryInterval(): number {
return this.retryUnit * this.retryInterval;
};
}
今の質問は、私は別の設定で新しいインスタンスを作成する方法である:2角度は、以下を参照して
私は、一般的なサービスを書かれていますか?
私はサブクラスに拡張してconfigureをパスすると思います。むしろ拡張クラスを作成するより良い方法はありますか?
設定は動的です。つまり、サーバーサイドのページに書き込まれるということです(バックエンドのハンドルバーを使用してテンプレートをレンダリングします)。
はありがとう、私はこのソリューションを実装しているし、この一つの方法は、(制限隔離することができますスコープ)をモジュールまたはコンポーネントに割り当てます。 – user3130446