ошибка основного сигнализатора asp.net во время рукопожатия websocket - PullRequest
0 голосов
/ 03 мая 2019

Извините за мой плохой английский.Я пытаюсь подключиться к SignalR Hub из SPA-приложения (Vue.JS).

Код со стороны клиента:

this.hubConnection = new HubConnectionBuilder()
    .withUrl('http://localhost:*****/testhub')
    .configureLogging(LogLevel.Information)
    .build()

Я получаю ошибку: Ошибка: Не удалось завершить согласование с сервером: SyntaxError: Неожиданный токен <в JSON в позиции 0 </em>

Затем я попытался:

this.hubConnection = new HubConnectionBuilder()
    .withUrl('http://localhost:*****/testhub', {
      skipNegotiation: true,
      transport: HttpTransportType.WebSockets
    })
    .configureLogging(LogLevel.Information)
    .build()

Ничего не изменилось (но я получаю другую ошибку):

Сбой подключения WebSocket к 'ws: // localhost: 50523 / testhub': Ошибка при рукопожатии WebSocket: Неожиданный код ответа: 200

Я проверил использование веб-сокетов вStartup.cs.Также я попытался изменить версию SignalR на стороне клиента, но это не может решить проблему.Когда я пытался подключить SignalR в многостраничных приложениях, я не вижу его.У меня это в первый раз.

Что я делаю не так?

Startup.cs

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.SpaServices.Webpack;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.WebSockets;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Microsoft.AspNetCore.Authorization;
using Newtonsoft.Json;
using Vue2Spa.Models;
using Vue2Spa.Controllers.App;
using Vue2Spa.Hubs;

namespace Vue2Spa
{
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)
    {
        // Add framework services.
        services.AddMvc().AddJsonOptions(options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore)
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        var connection = @"Server=.\SQLEXPRESS;Database=****;Trusted_Connection=True;";
        services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connection));

        services.AddIdentity<Account, IdentityRole>(options =>
        options.SignIn.RequireConfirmedEmail = true)
        .AddDefaultTokenProviders()
        .AddEntityFrameworkStores<ApplicationDbContext>();

        //JWT
        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        })
        .AddJwtBearer(options =>
            {
                options.RequireHttpsMetadata = false;
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidIssuer = AuthOptions.ISSUER,
                    ValidateAudience = true,
                    ValidAudience = AuthOptions.AUDIENCE,
                    ValidateLifetime = true,
                    IssuerSigningKey = AuthOptions.GetSymmetricSecurityKey(),
                    ValidateIssuerSigningKey = true,
                };
            })


        services.AddAuthorization(options =>
        {

        });
        /*services.AddAuthorization(options =>
        {
            options.DefaultPolicy = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme)
                .RequireAuthenticatedUser()
                .Build();
        });*/

        // Simple example with dependency injection for a data provider.
        services.AddSingleton<Providers.IWeatherProvider, Providers.WeatherProviderFake>();

        //File's parameters
        services.Configure<FormOptions>(o => {
            o.ValueLengthLimit = int.MaxValue;
            o.MultipartBodyLengthLimit = int.MaxValue;
            o.MemoryBufferThreshold = int.MaxValue;
        });

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

            // Webpack initialization with hot-reload.
            app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
            {
                HotModuleReplacement = true,
            });
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseStaticFiles();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");

            routes.MapRoute(
                name: "default1",
                template: "{controller=Admin}/{action=Index}/{id?}");

            routes.MapSpaFallbackRoute(
                name: "spa-fallback",
                defaults: new { controller = "Home", action = "Index" });

            routes.MapSpaFallbackRoute(
                name: "spa-fallback1",
                defaults: new { controller = "Admin", action = "Index" });
        });
        app.UseAuthentication();
        app.Use(async (context, next) =>
        {
            context.Response.Headers.Add("X-Xss-Protection", "1");
            await next();
        }).UseSignalR(route =>
        {
            route.MapHub<ChatHub>("/chat");
        });
    }
}
}

1 Ответ

1 голос
/ 03 мая 2019

Проблема была решена. Я переместил UseSignalR выше UseMvc.

...