#node.js #angular #typescript #websocket #socket.io
Вопрос:
В настоящее время я пишу угловой проект, который открывает соединение websocket с сервером NodeJS. Это и есть услуга:
export class WebsocketService {
socket : any;
constructor() { }
setupSocketConnection(){
this.socket = io(environment.SOCKET_ENDPOINT);
this.socket.emit('message', 'The client wants to intruduce itself to the server');
this.socket.on('broadcast', (data: string) => {
console.log(data);
});
}
disconnect() {
if (this.socket) {
this.socket.disconnect();
}
}
}
и это мой компонент:
export class AppComponent {
title = '-';
constructor(private websocket : WebsocketService) { }
ngOnInit(){
this.websocket.setupSocketConnection();
}
ngOnDestroy() {
this.websocket.disconnect();
}
}
Мой вопрос: как я могу передать «данные» из прослушивателя широковещательных событий в компонент, чтобы отобразить их там? Другой сервис был бы решением, но я не думаю, что он был бы хорошим. Я также мог бы поместить прослушиватель в функцию и вызвать ее из компонента, но не нарушит ли это концепции инкапсуляции сервисов?
Спасибо
Ответ №1:
Вы можете использовать BehaviorSubject, выполнив следующие действия:
Представьте себе отправку объекта JSON, содержащего поле «тип»: убедитесь, что данные, отправленные с помощью
1 — Серверная сторона:
JSON.stringify({type: "message", value: "whatever"})
2 — Теперь на стороне клиента
export class WebsocketService {
// Put the right data type here
message = new BehaviorSubject<string>('');
connection = new BehaviorSubject<string>('');
socket : any;
constructor() { }
setupSocketConnection(){
this.socket = io(environment.SOCKET_ENDPOINT);
this.socket.emit('message', 'The client wants to intruduce itself to the server');
this.socket.on('broadcast', (data: string) => {
const jsonObject = JSON.parse(data);
switch (jsonObject.type) {
case "message":
this.message.next(jsonObject.value);
break;
case "connection":
this.connection.next(jsonObject.value);
break;
default:
throw new Error('Unknown message type' jsonObject.type)
break;
}
});
}
disconnect() {
if (this.socket) {
this.socket.disconnect();
}
}
}
И, с другой стороны, просто подпишитесь на свои данные, которые выдают значения, связанные с поведением объекта.
export class AppComponent implements OnInit, OnDestroy {
title = '-';
subscriptions: Subscription[] = [];
constructor(private websocket : WebsocketService) { }
ngOnInit(){
this.websocket.setupSocketConnection();
this.websocket.message.subscribe(value => {
// Do your stuff here.
console.log(value);
})
this.websocket.connection.subscribe(value => {
// Do your stuff here.
console.log(value);
})
}
ngOnDestroy() {
this.websocket.disconnect();
this.subscriptions.forEach(s => s.unsubscribe());
this.subscription = [];
}
}
Комментарии:
1. Спасибо вам за вашу помощь! Я действительно застрял здесь, я не мог найти никаких ресурсов по этой проблеме. Я сделаю это сейчас. К сожалению, я не могу поддержать вас, потому что у меня нулевая репутация, иначе я бы
2. Нет проблем, я здесь для того, чтобы помочь, а не для того, чтобы понять суть ;).
3. Эй, у меня есть следующий вопрос. Я решил использовать один веб-сайт, который обрабатывает вход в систему и все остальное. Теперь мне интересно, как я мог бы изменить поведение объекта, чтобы предоставить компоненту только необходимые данные, а не все?
4. Почему бы вам не отправить JSON через сервер, а затем проанализировать его спереди. Обязательно добавьте поле «тип», затем на основе значения «тип» используйте другой объект поведения и подпишитесь на него для достижения своей цели ?