I know that SignalR can't have a return from client when invokation came from the server. On the github repository of SignalR I asked for a workaround (https://github.com/aspnet/SignalR/issues/1329) and they suggest me to get the result by sending it from the client to server to another method in the hub and so use TaskCompletionSource and some connection metadata to catch the result, but I'm stuck on how to do this
Controller Server :
[HttpPut("send/{message}")]
public async Task<IActionResult> SendMessage(string message)
{
if (!ModelState.IsValid) return BadRequest(ModelState.Values);
string connectionId = Request.Headers["connectionId"];
await _chatHubContext.Clients.Client(connectionId).InvokeAsync("send");
// Catch the call of MessageReceived and get the chat status
return new OkObjectResult(new EmptyJsonResult() { Result = "OK" });
}
Hub Server
public class ChatHub : Hub
{
public Task MessageReceive(bool chatStatus)
{
// Tell controller that message is received
}
}
Angular 4 client
import { Component, Inject } from '@angular/core';
import { HubConnection } from '@aspnet/signalr-client';
@Component({
selector: 'chat',
templateUrl: './chat.component.html',
styleUrls: ['./chat.component.css']
})
/** chat component*/
export class ChatComponent {
hubConnection: HubConnection;
chatStatus = false;
/** chat ctor */
constructor( @Inject('BASE_URL') private originUrl: string) {
this.hubConnection = new HubConnection(`${this.originUrl}chat`);
setInterval(() => {
this.chatStatus = !this.chatStatus;
},
5000);
this.hubConnection
.start()
.then(() => {
this.hubConnection.on('send', (message: string) => {
if (this.chatStatus) {
//send message
}
this.hubConnection
.invoke('messageReceived', this.chatStatus);
});
});
}
}
As you can see on this code, I don't know what to do in the controller method and the Hub method to know that the method MessageReceive was called and to get his return to send it back to the controller request.