Reputation: 459
I've created a chat system and now I'm trying to implement it by SignalR but the new message doesn't show in the target client's message box. It just happen after sending a new message to the server. However the new message and old messages shows correctly in the sender's browser
Here is my code:
baseUrl = environment.apiUrl;
hubUrl = environment.hubUrl;
private hubConnection: HubConnection;
private messageThreadSource = new BehaviorSubject<Message[]>([]);
messageThread$ = this.messageThreadSource.asObservable();
constructor(private http: HttpClient) { }
createHubConnection(userToken: UserToken, otherUserId: string, skip: string) {
this.hubConnection = new HubConnectionBuilder()
.withUrl(this.hubUrl + 'message?targetUserId=' + otherUserId + '&&skip=' + skip, {
accessTokenFactory: () => userToken.token
})
.withAutomaticReconnect()
.build()
this.hubConnection
.start()
.catch(error => console.log("SignalR Message Error : ", error));
this.hubConnection.on("ReceiveMessageThread", messages => {
this.messageThreadSource.next(messages);
});
this.hubConnection.on("NewMessage", message => {
this.messageThread$.pipe(take(1)).subscribe(messages => {
this.messageThreadSource.next([...messages,message]);
})
});
}
To explain more there is value in both message
and messages
in the NewMessage
hub connection. Having said that if I only pass message
, the target client's message box will become empty, I mean all the previous message eliminate from the HTML and at the same time only the latest message will show up in the sender client's message box.
this.messageThreadSource.next([message]);
Upvotes: 1
Views: 804
Reputation: 3611
I would have the following aproach:
public message: Message;
public messages: Message[] = [];
public startConnection = () => {
this.hubConnection = new signalR.HubConnectionBuilder()
.withUrl('https://localhost:5001/signalRHub')
.configureLogging(signalR.LogLevel.Information)
.withAutomaticReconnect()
.build();
this.hubConnection
.start()
.then(() => {
console.log('Connection started');
this.addMessageListener();
})
.catch(err => console.log('Error while starting connection: ' + err))
// Add message to the chat
public newMessage(message: string) {
this.hubConnection.invoke("NewMessage", message).catch((ex) => {
console.log(ex);
});
}
// Add chat message listener
private addMessageListener = () => {
this.hubConnection.on('BroadcastMessage', (message: Message) => {
this.message = message;
this.messages.push(this.message);
console.log(message);
});
}
Upvotes: 0
Reputation: 359
I have a similar implementation of code for another kind of data. But I still receive two updates, one for the initial, and another one with current changes. What I do on my code i(i'll adapt your's to mine)
this.hubConnection.on("ReceiveMessageThread", messages => {
this.messageThreadSource.next(messages);
});
this.hubConnection.on("NewMessage", message => {
this.messageThreadSource.next(message);
});
And on the subscription side I'll do something like this.
this.yourservice.messageThreadSource.subscribe((message: any) => {
this.message = [...messages,message];
//or
this.message.concat(message)
});
The only difference is that I'm mergin the messages and messgge on the final ts document using the subscription not on the signal responses. And in this code i'm using this.message
as a variable that will display all the messages on the html
Upvotes: 1