I've been researching this issue for 3 days now and cannot find a solution. I created a SignalR Hub with the following code:
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
namespace Messenger.Hubs
{
public class MessengerHub : Hub
{
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
}
Simple enough, the startup code is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Messenger.Hubs;
namespace Messenger
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddSignalR();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseSignalR(routes =>
{
routes.MapHub<ChatHub>("c:/myapp/Messenger");
});
app.UseMvc();
}
}
}
I pretty much cut and pasted the code from a solution posted on the internet somewhere, I forget where, not stackoverflow though. I then created the following client in a Xamarin (v4.12.3.81) project using Visual Studio 2017 (v15.9.10). That code is:
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR.Client;
namespace SignalR.Client.Hubs
{
public class SampleHub
{
// MessengerHub is a appliaction folder aliased as MessengerHub
// the direct path on the machine is c:\mywebapp\messenger
private const string _hubUrl = "http://example.com/MessengerHub";
private readonly HubConnection _hubConnection;
public event EventHandler<string> OnMessageReceived;
public SampleHub()
{
var builder = new HubConnectionBuilder().WithUrl(_hubUrl);
_hubConnection = builder.Build();
}
public async Task<bool> ConnectAsync()
{
try
{
await _hubConnection.StartAsync();
_hubConnection.On("messageReceived", (string platform, string message) =>
{
if (OnMessageReceived != null)
{
OnMessageReceived(this, string.Format("{0}: {1}", platform, message));
}
});
}
catch (Exception ex)
{
var msg = ex.Message;
//Console.WriteLine($"Connection error: {ex.Message}");
return false;
}
return true;
}
public async Task<int> GetNumberAsync(int number)
{
return await _hubConnection.InvokeAsync<int>("GetNumber", number);
}
public Task Send(string message)
{
return _hubConnection.SendAsync("Send", message);
}
}
}
The code in the activity that uses that client is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Views.InputMethods;
using SignalR.Client.Hubs;
namespace MyXamarinApp
{
[Activity(Label = "Messenger")]
public class Messenger : Activity
{
protected override async void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your application here
SetContentView(Resource.Layout.Messenger);
RequestedOrientation = Android.Content.PM.ScreenOrientation.Portrait;
try
{
var input = FindViewById<EditText>(Resource.Id.Input);
var messages = FindViewById<ListView>(Resource.Id.Messages);
var inputManager = (InputMethodManager)GetSystemService(InputMethodService);
var adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, new List<string>());
messages.Adapter = adapter;
var hub = new SampleHub();
await hub.ConnectAsync(); // <---- fails here
input.EditorAction +=
delegate
{
inputManager.HideSoftInputFromWindow(input.WindowToken, HideSoftInputFlags.None);
if (string.IsNullOrEmpty(input.Text))
return;
hub.Send(input.Text);
input.Text = "";
};
hub.OnMessageReceived +=
(sender, message) => RunOnUiThread(() =>
adapter.Add(message));
}
catch (Exception ex)
{
var msg = ex.Message;
}
}
}
}
The hub is (I believe) running correctly on the server, I set logging on and this is what is in the log:
Hosting environment: Production
Content root path: C:\mywebapp\Messenger
Application started. Press Ctrl+C to shut down.
The attempt to connect to the hub generates the following error:
{System.Net.Http.HttpRequestException: 404 (Not Found)
at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode () [0x0002a] in <25ebe1083eaf4329b5adfdd5bbb7aa57>:0
at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection+<NegotiateAsync>d__44.MoveNext () [0x00226] in <843c441fa9954906b53e3710152bebb9>:0
--- End of stack trace from previous location where exception was thrown
--- at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection+<GetNegotiationResponseAsync>d__51.MoveNext () [0x00077] in <843c441fa9954906b53e3710152bebb9>:0
--- End of stack trace from previous location where exception was thrown
---
at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection+<SelectAndStartTransport>d__43.MoveNext () [0x00169] in <843c441fa9954906b53e3710152bebb9>:0
--- End of stack trace from previous location where exception was thrown
---
at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection+<StartAsyncCore>d__40.MoveNext () [0x00118] in <843c441fa9954906b53e3710152bebb9>:0
--- End of stack trace from previous location where exception was thrown
--- at System.Threading.Tasks.ForceAsyncAwaiter.GetResult () [0x0000c] in <843c441fa9954906b53e3710152bebb9>:0
at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection+<StartAsync>d__39.MoveNext () [0x0008b] in <843c441fa9954906b53e3710152bebb9>:0
--- End of stack trace from previous location where exception was thrown
--- at Microsoft.AspNetCore.SignalR.Client.HttpConnectionFactory+<ConnectAsync>d__3.MoveNext () [0x0009d] in <d50de232736c4c8f910083ea0cb358a8>:0
--- End of stack trace from previous location where exception was thrown
---
at Microsoft.AspNetCore.SignalR.Client.HttpConnectionFactory+<ConnectAsync>d__3.MoveNext () [0x00142] in <d50de232736c4c8f910083ea0cb358a8>:0
--- End of stack trace from previous location where exception was thrown
---
at Microsoft.AspNetCore.SignalR.Client.HubConnection+<StartAsyncCore>d__47.MoveNext () [0x00130] in <f381011e9b214489bcb373743f31ed9d>:0
--- End of stack trace from previous location where exception was thrown
---
at System.Threading.Tasks.ForceAsyncAwaiter.GetResult () [0x0000c] in <f381011e9b214489bcb373743f31ed9d>:0
at Microsoft.AspNetCore.SignalR.Client.HubConnection+<StartAsync>d__39.MoveNext () [0x00091] in <f381011e9b214489bcb373743f31ed9d>:0
--- End of stack trace from previous location where exception was thrown
---
at SignalR.Client.Hubs.SampleHub+<ConnectAsync>d__6.MoveNext () [0x00037] in C:\Users\<username>\Documents\Visual Studio 2017\Projects\signalr_client\signalr_client\Resources\layout\Client.cs:28 }
This is what I see in the IIS Log for the site.
"POST /MessengerHub/negotiate HTTP/1.1" 303 446
"GET /MessengerHub/negotiate HTTP/1.1" 404 1509
I have no idea what to try next.
I struggled with this error today and after some rather wasted time I had simple forgot to add:
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<FooHub>("/FooHub");
});
To the Startup.cs >> public void Configure(...) in my .NET 5 ASP.NET application.
Things have changed a little since this was originally posted (and I did see some Xamarin) but hopefully this gives somebody some guidance in the future.
I had the same problem with SignalR NetCore 5, Blazor webassembly project when deployed to IIS, worked fine in localhost on dev machine.
The solution was to use full url in the hub connection: First include hub endpoint in the Startup.cs
endpoints.MapHub<BroadcastHub>("/broadcastHub");
Then when setting up the hub connection, instead
hubConnection = new HubConnectionBuilder()
.WithUrl(navigationManager.ToAbsoluteUri("/broadcastHub")
.Build();
use full url:
hubConnection = new HubConnectionBuilder()
.WithUrl("http://myserver.com/bcwa/broadcastHub")
.Build();
bcwa is my IIS deploy folder
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With