通过协商404(未找到)连接到SignalR Hub失败

时间:2019-03-28 17:05:12

标签: c# asp.net-core xamarin.android visual-studio-2017 signalr

我已经研究此问题3天了,找不到解决方案。我用以下代码创建了SignalR Hub:

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);
        }
    }
}

很简单,启动代码是:

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();
        }
    }
}

我几乎剪切并粘贴了发布在Internet上某个地方的解决方案中的代码,但我忘记了在哪里,而不是stackoverflow。然后,我使用Visual Studio 2017(v15.9.10)在Xamarin(v4.12.3.81)项目中创建了以下客户端。该代码是:

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);
        }
    }
}

使用该客户端的活动中的代码为:

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;
            }
        }
    }
}

(我认为)集线器在服务器上正确运行,我设置了登录功能,这就是日志中的内容:

Hosting environment: Production
Content root path: C:\mywebapp\Messenger
Application started. Press Ctrl+C to shut down.

尝试连接到集线器会产生以下错误:

{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 }

这是我在该站点的IIS日志中看到的。

"POST /MessengerHub/negotiate HTTP/1.1" 303 446
"GET /MessengerHub/negotiate HTTP/1.1" 404 1509

我不知道下一步该怎么做。

2 个答案:

答案 0 :(得分:0)

我今天遇到了这个错误,在浪费了一些时间之后,我忘记了添加:

  #include <iostream>
  #include <cstring>
  
  using namespace std;
 
  void translate(char human[], char dog[]); //human is input and dog is output
 
  int main()
  {
      char human[100], dog[100];
 
      cout << "Enter a string: ";
      cin.getline(human, 100);
 
      for (int i = 0; i < strlen(human); i++)
      {
          dog[i] = human[i];
      }
      dog[strlen(human)] = '\0';
 
      cout << dog << endl;
 
 
      return 0;
  }
 
 
  void translate (char human[], char dog[])
  {
      for (int i = 0; i < strlen(human); i++)
      {
          dog[i] = human[i];
      }
 
  }

到 Startup.cs >> public void Configure(...) 在我的 .NET 5 ASP.NET 应用程序中。

自从最初发布以来,情况发生了一些变化(我确实看到了一些 Xamarin),但希望这能在未来为某人提供一些指导。

答案 1 :(得分:0)

我在 SignalR NetCore 5 中遇到了同样的问题,Blazor webassembly 项目在部署到 IIS 时在开发机器上的本地主机中运行良好。

解决方案是在集线器连接中使用完整的 url: 首先在 Startup.cs 中包含集线器端点

 endpoints.MapHub<BroadcastHub>("/broadcastHub");

然后在设置集线器连接时,改为

   hubConnection = new HubConnectionBuilder()
              .WithUrl(navigationManager.ToAbsoluteUri("/broadcastHub")
                 .Build();

使用完整网址:

     hubConnection = new HubConnectionBuilder()
            .WithUrl("http://myserver.com/bcwa/broadcastHub")
            .Build();

bcwa 是我的 IIS 部署文件夹