user3748973
user3748973

Reputation: 459

SignalR the new message does not shows in target client's message box - Angular

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

Answers (2)

Kiril1512
Kiril1512

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

Florencia Cames
Florencia Cames

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

Related Questions