有一个websocket echo服务,用于发送和接收消息:
@Injectable()
export class NotificationsService {
private ws = new $WebSocket('wss://echo.websocket.org');
wsSendMessage(message: string = `Message ${Math.random()}`): void {
this.ws.send(message);
}
wsGetMessages(): Observable<string> {
return Observable.from(this.ws.getDataStream())
.map((res: any) => res.data);
}
}
通知组件订阅此observable并显示通知下拉列表中的所有消息:
getMessages(): void {
this.notificationsService.wsGetMessages().subscribe(
(message: string) => {
this.messages.unshift(message);
},
(err: any) => console.log(err)
);
}
当打开通知下拉列表面板时,我需要在导航栏组件中显示未读消息的数量并将其设置为0。我对如何做到没有任何想法,所以我需要你的帮助...
P.S。
现在,websocket echo服务是:
@Injectable()
export class NotificationsService {
private ws = new $WebSocket('wss://echo.websocket.org');
wsSendMessage(message: string = `Message ${Math.random()}`): void {
this.ws.send(message);
}
wsGetMessages(): Observable<Object> {
return Observable.from(this.ws.getDataStream())
.map((res: any) => res.data);
}
messagesReadStream(msgArray: Object[]): Observable<Object> {
return Observable.from(msgArray);
}
}
和通知组件是:
export class Notifications implements OnInit {
messagesAll:string[] = [];
messagesRead:string[] = [];
newMessagesNumber:number = 0;
constructor(private notificationsService: NotificationsService) {
}
addMessage(): void {
this.notificationsService.wsSendMessage();
}
getMessages(): void {
this.notificationsService.wsGetMessages()
.subscribe(
(message: any) => this.messagesAll.unshift(message),
(err: any) => console.error(err)
);
}
readMessages(): void {
this.messagesRead = this.messagesAll.slice();
this.notificationsService.messagesReadStream(this.messagesRead)
.switchMap(() =>
this.notificationsService
.wsGetMessages()
.scan((unread, _) => unread + 1, 0)
.startWith(0))
.subscribe(
(count: number) => this.newMessagesNumber = count,
(err: any) => console.error(err)
);
}
ngOnInit(): void {
this.getMessages();
}
}
使用模板:
<button type="button" class="btn btn-primary-outline btn-sm" (click) = "addMessage()">
Add message
</button>
<button type="button" class="btn btn-primary-outline btn-sm" (click) = "readMessages()">
Read messages
</button>
<div style="margin-top: 1rem">
<span class="circle bg-warning fw-bold">
{{newMessagesNumber}}
</span>
</div>
现在,如果点击button 'Add message'
我的计数器不会更改0
的值。只有当我点击button 'Add message'
,然后点击button 'Read messages'
,然后再点击button 'Add message'
,计数器就会开始正常运行。你能解释一下,问题是什么?
答案 0 :(得分:2)
您需要多个Observable
。一个包含计数,一个用于在读取消息时发出信号。前者将使用wsGetMessage
流,而后者必须连接到Observable,只要打开通知面板就会触发。
const panelOpened: Observable<any> = //..Need a signalling mechanism for when the messages get read
const unreadCount: Observable<number> = messagesRead.switchMap(() =>
this.notificationsService
.wsGetMessages()
//Just count all of the messages as they come in.
.scan((unread, _) => unread + 1, 0)
//Make sure it always gets reset to zero
.startWith(0));
//Subscribe to updates on count changes.
unreadCount.subscribe(count => this.unreadMessageCount = count);