I am trying to implement SignalR using .Net Core Web API (Server side) and Console application (Client Side) to understand the working.
Here is my startup.cs code :
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "SignalR", Version = "v1" });
});
//Service for SignalR
services.AddSignalR();
services.AddCors(c =>
{
c.AddPolicy("AllowOrigin", options => options.AllowAnyOrigin());
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "SignalR v1"));
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseCors(o=>o.AllowAnyOrigin());
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
//Endpoint map for ChatHub, which I've created
endpoints.MapHub<ChatHub>("/chathub");
});
}
Here is my ChatHub Class:
public class ChatHub : Hub
{
public async Task SendMessage(string message)
{
await Clients.All.SendAsync("ReceiveMessage", message);
}
}
Here is my Console application ( Created as SignalR Client):
static async Task Main(string[] args)
{
try
{
HubConnection connection = new HubConnectionBuilder().WithUrl("https://localhost:44340/chathub").WithAutomaticReconnect().Build();
await connection.StartAsync();
if(connection.State == HubConnectionState.Connected)
{
Console.WriteLine("Connected ... Please type message now");
var message = "Hey";
//Getting hit to SendMessage method defined in ChatHub Class
await connection.InvokeAsync("SendMessage", message);
Console.WriteLine(connection.ConnectionId);
/*
Connection.On is not working and unable to writeline on console.
I am expecting result Hey on Console.
*/
connection.On<string>("ReceiveMessage", m =>
{
Console.WriteLine(m);
});
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
I am expecting Result :
ConnectionId
Hey
But I am getting:
ConnectionId
CodePudding user response:
Because your connection.On
register event it too late, the SignalR is broadcast completed on .Net Core Web API. So you can't get the message.
You can move connection.On
register event before connection.InvokeAsync
method then you can see the 'Hey' message.
// ...
// Register event
connection.On<string>("ReceiveMessage", m =>
{
Console.WriteLine(m);
});
if(connection.State == HubConnectionState.Connected)
{
Console.WriteLine("Connected ... Please type message now");
var message = "Hey";
await connection.InvokeAsync("SendMessage", message);
Console.WriteLine(connection.ConnectionId);
}
// Result:
// Connected ... Please type message now
// Hey
// ConnectionId
If you want ConnectionId
message before Hey
message, you can change this.
// ...
// Register event
connection.On<string>("ReceiveMessage", m =>
{
Console.WriteLine(m);
});
if(connection.State == HubConnectionState.Connected)
{
Console.WriteLine("Connected ... Please type message now");
var message = "Hey";
// call async method and wait later
var task = connection.InvokeAsync("SendMessage", message);
Console.WriteLine(connection.ConnectionId);
// wait SendMessage
await task;
}
// Result:
// Connected ... Please type message now
// ConnectionId
// Hey