尝试使用Signalr Core时缺少“连接升级”标题

时间:2019-01-11 20:40:36

标签: c# iis .net-core http-headers asp.net-core-signalr

我正在使用Java / kotlin客户端应用程序和在AWS Elastic beantalk上运行的基于.Net Core的服务器创建应用程序。我正在尝试使用Signalr Core库实现实时通知,但是遇到了一些问题。似乎每当我尝试在客户端和服务器之间建立连接时,尝试升级到Websocket时握手都会失败。

  

Java错误:WebSocket因错误而关闭:预期的“连接”标头值为“升级”,但为“空”。

似乎服务器发出的响应在所有情况下都是正确的,只是缺少标题“ Connection”:“ Upgrade”并导致我的代码失败。我已经对此进行了广泛研究,但在任何方面都没有成功。

我的服务器正在使用IIS 10和Net Core 2.2在“ Window Server 2016数据中心”实例上运行。

我的代码:

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.AddRouting(options => options.LowercaseUrls = true);
        services.AddMvc();
        services.AddSignalR(options =>
        {
            options.EnableDetailedErrors = true;
        });
    }

    // 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();
            app.UseBrowserLink();
        }

        app.UseDefaultFiles(new DefaultFilesOptions
        {
               DefaultFileNames = new
               List<string> { "index.html" }
        });



        app.Use(async (context, nextMiddleWare) =>
        {
            context.Response.OnStarting(() =>
            {
                if (!context.Response.Headers.Keys.Contains("Connection"))
                {
                    context.Response.Headers.Add("Connection", "Upgrade");
                }
                else
                {
                    context.Response.Headers["Connection"] = "Upgrade";
                }

                return Task.FromResult(0);
            });

            await nextMiddleWare();

            context.Response.OnCompleted(() =>
            {
                Console.WriteLine("LOG: Hitting Custom Middleware with status code: {0}", context.Response.StatusCode);
                return Task.FromResult(0);
            });
            ;
        });

        app.UseSignalR(routes =>
        {

            routes.MapHub<MainHub>("/mainHub");
        });

        app.UseMvc();

...

class Program
{
    public static void Main(string[] args)
    {

        SetEbConfig();

        BuildWebHost(args).Run();
    }

    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>()
            .Build();

    private static void SetEbConfig()
    {
        var tempConfigBuilder = new ConfigurationBuilder();

        tempConfigBuilder.AddJsonFile(
            @"C:\Program Files\Amazon\ElasticBeanstalk\config\containerconfiguration",
            optional: true,
            reloadOnChange: true
        );

        var configuration = tempConfigBuilder.Build();

        var ebEnv =
            configuration.GetSection("iis:env")
                .GetChildren()
                .Select(pair => pair.Value.Split(new[] { '=' }, 2))
                .ToDictionary(keypair => keypair[0], keypair => keypair[1]);

        foreach (var keyVal in ebEnv)
        {
            Environment.SetEnvironmentVariable(keyVal.Key, keyVal.Value);
        }
    }
}

...

 public class MainHub : Hub
{
    public async Task SendMessage(string user, string message)
    {

        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }

    public async Task BroadcastOrder(string groupName, Order order)
    {
        await Clients.Group(groupName).SendAsync("New Order", order);
    }
    public  Task JoinGroup(string groupName)
    {

        return Groups.AddToGroupAsync(Context.ConnectionId, groupName);
    }

    public Task LeaveGroup(string groupName)
    {
        return Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);
    }

    public override async Task OnConnectedAsync()
    {
        await Groups.AddToGroupAsync(Context.ConnectionId, "SignalR Users");
        await base.OnConnectedAsync();
    }
    public override async Task OnDisconnectedAsync(Exception exception)
    {
        await Groups.RemoveFromGroupAsync(Context.ConnectionId, "SignalR Users");
        await base.OnDisconnectedAsync(exception);
    }
}

正如您在Startup.cs中看到的那样,我什至尝试使用中间件将标头手动添加到响应中,但标头仍不会出现在客户端中。我可能不完全了解中间件管道的工作方式(因为我对其中的大多数还相当陌生)或其他因素在起作用。

0 个答案:

没有答案