【问题标题】:.Net Core 2 Signalr alpha2 Hub not working.Net Core 2 Signalr alpha2 Hub 不工作
【发布时间】:2018-02-22 02:24:13
【问题描述】:

我有一个无法解决的重大问题。我有一个带有 jwt auth 的.net core 2 项目,并试图让一个基本的信号器集线器测试工作。来自客户端的连接似乎可以正常工作,但连接会立即断开,并出现 204 代码。

我的集线器在我的前端 UI 之外的另一个 URL 上运行,因此涉及到 CORS。

**我删除了真实密钥和我的项目名称

这是客户端控制台输出的内容:

这是我的启动代码:

public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        services.Configure<ConnectionStrings>(Configuration.GetSection("ConnectionStrings"));
        services.Configure<DiAssemblies>(Configuration.GetSection("DiAssemblies"));
        services.Configure<StripeSettings>(Configuration.GetSection("Stripe"));
        services.Configure<AzureStorageSettings>(Configuration.GetSection("AzureStorageSettings"));

        // Add framework services.
        services.AddApplicationInsightsTelemetry(Configuration);
        services.AddCors(options =>
        {
            options.AddPolicy("CorsPolicy",
                x => x.AllowAnyOrigin()
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowCredentials());
        });


        services.AddCors();

        services.AddIdentity<testApp.Identity.ApplicationUser, IdentityRole>()
        .AddEntityFrameworkStores<testApp.Identity.Context>()
        .AddDefaultTokenProviders();

        services.AddAuthentication(sharedOptions =>
        {
            sharedOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
            sharedOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            sharedOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;


        })
            .AddJwtBearer(options =>
            {
                options.RequireHttpsMetadata = false;
                options.SaveToken = true;

                options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
                {
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("authkeyasdfasdfasdfsadfasdfda")),
                    ValidIssuer = "https://testApp.com/",
                    ValidAudience = "https://testApp.com/",

                };
                options.Events = new JwtBearerEvents
                {

                    OnAuthenticationFailed = context =>
                    {
                        Debug.WriteLine("Auth issue");
                        Debug.WriteLine(context.Exception);
                        return Task.CompletedTask;
                    },

                    OnMessageReceived = context =>
                    {
                        if (!context.Request.Headers.ContainsKey("Authorization") && !string.IsNullOrEmpty(context.Request.Query["authToken"]))
                        {
                            context.Request.Headers.Add("Authorization", context.Request.Query["authToken"]);
                        }
                        return Task.CompletedTask;
                    },
                    OnChallenge = context =>
                    {
                        Debug.WriteLine("Auth issue");
                        Debug.WriteLine(context.Error);
                        Debug.WriteLine(context.ErrorDescription);
                        return Task.CompletedTask;
                    }
                };
            });

        services.AddMemoryCache();

        services.AddMvc().AddJsonOptions(options =>
        {
            options.SerializerSettings.ContractResolver =
                new CamelCasePropertyNamesContractResolver();
            options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
        });

        services.AddSockets();
        services.AddSignalRCore();

        var builder = new ContainerBuilder();

        // Register dependencies, populate the services from
        // the collection, and build the container. If you want
        // to dispose of the container at the end of the app,
        // be sure to keep a reference to it as a property or field.
        //builder.RegisterType<MyType>().As<IMyType>();
        builder.Populate(services);
        var diHelper = new DiHelper();
        var diAssemblies = Configuration.GetValue<string>("DiAssemblies:List");
        var assemblies = diHelper.GetAssemblies(diAssemblies.Split(',').ToList());
      //  Console.Write(diAssemblies);
        builder.RegisterAssemblyModules(assemblies);

        ApplicationContainer = builder.Build();

        //foreach(var assembly in assemblies)
        //    services.AddMvc().AddApplicationPart(assembly).AddControllersAsServices();

        // Create the IServiceProvider based on the container.
        return new AutofacServiceProvider(ApplicationContainer);
    }

    // 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.UseCors(
            options => options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader()
        );


        app.UseAuthentication();


        app.UseMvc();

        app.UseSignalR(routes =>
        {
            routes.MapHub<ChatHub>("chat");
        });
    }
}

我的 Hub(任何方法的断点都不会被命中)

public class ChatHub : Hub
    {
        public ChatHub()
        {
            var t = 0;
        }


        public override async Task OnConnectedAsync()
        {
            await Clients.Client(Context.ConnectionId).InvokeAsync("send", "connection made");

            await base.OnConnectedAsync();
        }

        public Task Send(string message)
        { 
            return Clients.All.InvokeAsync("send", message); 
        }
    }

客户端javascript:

<script>
      window.connection;
      window.connection = new signalR.HubConnection("https://localhost:44367/chat?authToken=" + 'bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.yyJzdWIiOiJhYzNkMTU3OC05YjU5LTRmNzQtOWMxYi01MWZlYjk2YmQ4YzEiLCJqdGkiOiJidnRlc3QxIiwiZXhwIjoxTYI2NjY1OTM3LCJpc3MiOiJodHRwczovL2Jpc3ZpbmUuY29tLyIsImF1ZCI6Imh0dHBzOi1vYmlzdmluZS5jb20vIn0.GxycqmyVsdHkW3M5yRH7arGkR3K-jAE2zrPrgoJnh-M', 
                                { transport: signalR.TransportType.LongPolling });

      window.connection.on('send', function(message) {
        alert(message);
      });


      window.connection.start().then(function() {
        console.log("SignalR Connected: Chat");
        window.connection.invoke('send',"hi").then(function (chats) {
          console.log(chats);
        });
      }, function () {

      });
    </script>

【问题讨论】:

  • 能不能去掉传输:signalR.TransportType.LongPolling
  • 没有信号器 2 要求您设置传输
  • Signalr 2 或 .net core 2。为什么你默认使用长轮询而不是使用 web 套接字?
  • 在 Windows 7 上测试
  • 嗯,让我检查一下我的项目,看看是否有不同之处。您的身份验证中间件在哪里拦截您的 get 参数并将其转换为 jwt?

标签: .net .net-core signalr


【解决方案1】:

我知道这一定很容易,但希望如果其他人遇到这个问题,它也会帮助他们。

拔掉头发后,我后退了一步,发现日志显示已找到集线器,我注意到隐藏了几行,表明另一个 mvc 控制器也在被调用。找到控制器后,我注意到它没有属性 [Route("api/[controller]")]。

添加了它,然后一切都开始工作了!似乎每个控制器都需要至少设置一个路由,否则 mvc 将在 signalr 有机会完全触发之前接听电话。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-20
    • 1970-01-01
    • 2023-01-30
    • 1970-01-01
    • 1970-01-01
    • 2020-11-20
    相关资源
    最近更新 更多