Я пытаюсь реализовать переподключение веб-сокетов в Angular 8. Ниже приведен пример кода. У меня есть 2 службы и 1 подписка в шаблоне для перехвата сообщений из веб-сокета.
Ниже приведен основной сервис, который создает соединение через веб-сокет.
export class WebsocketService {
constructor() {}
private subject: Rx.Subject<MessageEvent>;
public connect(url): Rx.Subject<MessageEvent> {
if (!this.subject) {
this.subject = this.create(url);
console.log("Successfully connected: " + url);
}
return this.subject;
}
private create(url): Rx.Subject<MessageEvent> {
let ws = new WebSocket(url);
let observable = Rx.Observable.create((obs: Rx.Observer<MessageEvent>) => {
ws.onmessage = obs.next.bind(obs);
ws.onerror = obs.error.bind(obs);
ws.onclose = (e) => {
console.log('Socket is closed. Reconnect will be attempted in 5 second.', e.reason);
setTimeout(() => {
this.connect(url);
}, 5000);
};
return ws.close.bind(ws);
});
let observer = {
next: (data: Object) => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify(data));
}
}`enter code here`
};
return Rx.Subject.create(observer, observable);
}
}
Следующий фрагмент - это служба чата где мы реализуем метод получения субъекта из веб-сокета:
@Injectable()
export class ChatService {
public messages: Subject<Message>;
constructor(wsService: WebsocketService) {
}
connection() {
return <Subject<any>>this.wsService.connect(CHAT_URL)
.map(
(response: MessageEvent) => {
return JSON.parse(response.data);
},
);
}
}
А из шаблона мы подписываемся на тему из веб-сокета:
export class AppComponent {
constructor(private chatService: ChatService) {
this.socketInfo = chatService.connection.subscribe(msg => {
console.log("Response from websocket: " + msg);
});
}
Я пытаюсь реализовать из этой структуры Возможность переподключения в случае, если сервер не работает, как вы можете видеть, из-за ошибки, которую я сделал setTimeout
для переподключения.
ws.onclose = (e) => {
console.log('Socket is closed. Reconnect will be attempted in 5 second.', e.reason);
setTimeout(() => {
this.connect(url);
}, 5000);
};
Это дает мне возможность переподключать веб-сокет при ошибке. Однако подписка с темой производится 1 раз, и я считаю, что для обновления новой информации мне нужно сделать setInterval
в шаблоне, чтобы проверить соединение через определенное время (возможно 30 с c.). Я не уверен, что это лучшее решение, если у вас есть лучшие идеи, пожалуйста, поделитесь со мной, буду признателен. Есть ли лучший способ получения обновленной подписки в шаблоне от темы и переподключения веб-сокета, если сервер не работает?