Как работать с SignalR в ядре asp.net 3.0 - PullRequest
3 голосов
/ 31 октября 2019

Hy, Мы работаем над основным проектом asp.net, который зависит от Signal R. Наконец, мы обновили наш проект с ядра asp.net 2.2 до 3.0, и Signal R перестал работать. В документации мы все настроили (я думаю правильно), но все равно не работает. Что мы пропустили?

API Asp.net Core 3.0

Запуск:

public class Startup
{
     private readonly string corsPolicy = "CorsPolicy";
     private static string[] AllowdOrigins() => return new string[] {"localhost:4200","example.com"};

     public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            ConfigureAuthentication(services);


            ///MICROSOFT SQL DATABASE
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")
            ));

            services.Configure<ApiBehaviorOptions>(options =>
            {
                options.SuppressModelStateInvalidFilter = true;
            });

            services.Configure<ForwardedHeadersOptions>(options =>
            {
                options.KnownProxies.Add(IPAddress.Parse("XX.XX.XX.XX"));
            });

            services.AddSignalR();
            services.AddControllers();

            //services dependencies

        }


        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseHttpsRedirection();
            app.UseRouting();
            app.UseCors(corsPolicy);

            //app.UseForwardedHeaders(new ForwardedHeadersOptions
            //{
            //    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
            //});

            app.UseAuthentication();
            app.UseAuthorization();


            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
                endpoints.MapHub<ChatHub>("/chat");
            });



            DummyData.Initialize(app);
        }
        private void ConfigureAuthentication(IServiceCollection services)
        {
            services.AddCors(options =>
            {
                options.AddPolicy(corsPolicy,
                builder =>
                {
                    builder
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowAnyOrigin()
                    .AllowCredentials()
                    .WithOrigins(AllowdOrigins());
                });
            });

            services.AddHttpContextAccessor();



            // configure strongly typed settings objects
            var appSettingsSection = Configuration.GetSection("AppSettings");
            services.Configure<AppSettings>(appSettingsSection);

            // configure jwt authentication
            var appSettings = appSettingsSection.Get<AppSettings>();
            var key = Encoding.ASCII.GetBytes(appSettings.Secret);

            services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(x =>
            {
                x.RequireHttpsMetadata = false;
                x.SaveToken = true;
                x.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(key),
                    ValidateIssuer = false,
                    ValidateAudience = false
                };
            });
        }
}

Chathub:

[EnableCors("CorsPolicy")]
    public class ChatHub : Hub
    {
        private static Dictionary<string, int> onlineClientCounts = new Dictionary<string, int>();
        private static readonly string FrontPrefix = "_FRONT";

        public ChatHub()
        {
        }

        [HubMethodName("ConnectFrontend")]
        public async Task ConnectFrontend(int sessionId)
        {

            //////
        }

        [HubMethodName("ConnectDevice")]
        public async Task ConnectDevice(int sessionId)
        {
            //// This method should be called but it isn't.
        }

        public void DisConnect(int sessionId, int userId)
        {
           //////////
        }

        [HubMethodName("SendJsonToFrontends")]
        public async Task SendJsonToFrontends(int sessionId, string jsonString)
        {
///
        }

        [HubMethodName("SendJsonToAll")]
        public async Task SendJsonToAll(int sessionId, string jsonString)
        {
////
        }
    }

Угловой проект

SignalRService

export class SignalRService {

  private connection: signalR.HubConnection;

  public newMessage = new Subject<SocketMessage>();

  constructor() {

  }

  public connectFront() {

    this.connection = new signalR.HubConnectionBuilder()
        .withUrl("http://localhost:2525/chat")//(environment.baseSignalR)
        .configureLogging(signalR.LogLevel.Trace)
        .build();


    this.connection.on("ReceiveJson", data => { this.handleJsonMessage(data) });

    //handles the first connection message
    this.connection.start().then(() => this.sendConnectionMessage());

    //handles the incomming messages
    this.connection.on("ReceiveJson", data => this.handleJsonMessage(data));
    this.connection.on("ReceiveJsonFrontend", data => this.handleJsonMessage(data));
  }

  private sendConnectionMessage() {
    var sessionId = sessionStorage.getItem("SessionId");
    if (sessionId != null) {
        this.connection.invoke("ConnectFrontend", sessionId).catch((error) => { debugger; console.log(error); });
    }
  }

  public sendWebsocketMessageToAll(msg: SocketMessage) {
    var sessionId = sessionStorage.getItem("SessionId");
    if (sessionId != null) {
      this.connection.invoke("SendJsonToAll", sessionId, JSON.stringify(msg)).catch((error) => console.log(error));
    }
  }

  public sendWebsocketMessageToFrontend(msg: SocketMessage) {
    var sessionId = sessionStorage.getItem("SessionId");
    if (sessionId != null) {
      this.connection.invoke("SendJsonToFrontends", sessionId, JSON.stringify(msg)).catch((error) => console.log(error));
    }
  }

  private handleJsonMessage(data: string) {
    this.newMessage.next(this.getSocketMessage(data));
  }

  public getSocketMessage(data: string): SocketMessage {
    var msg: SocketMessage = JSON.parse(data);
    return msg;
  }

  public disconnect() {
    this.connection.stop();
  }
}

угловой выход: enter image description here

APIвыход: enter image description here

Ответы [ 3 ]

1 голос
/ 14 ноября 2019

Что ж, я наконец-то понял это с помощью Тони,

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

Когда я изменил его на строки, это сработало.

1 голос
/ 31 октября 2019

Просто создайте API веб-приложения с угловым шаблоном, вы можете просмотреть мой код для вашей ссылки

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
        services.AddSpaStaticFiles(configuration =>
        {
            configuration.RootPath = "ClientApp/dist";
        });
        services.AddSignalR().AddJsonProtocol(options =>
        {
            options.PayloadSerializerOptions.WriteIndented = false;
        });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
        }

        app.UseStaticFiles();
        if (!env.IsDevelopment())
        {
            app.UseSpaStaticFiles();
        }

        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller}/{action=Index}/{id?}");
            endpoints.MapHub<ChatHub>("/chatHub");
        });

        app.UseSpa(spa =>
        {
            spa.Options.SourcePath = "ClientApp";

            if (env.IsDevelopment())
            {
                spa.UseAngularCliServer(npmScript: "start");
            }
        });
    }

На стороне FE. Примечание: используйте новый пакет @ microsoft / signalr

import * as signalR from "@microsoft/signalr";
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
    title = 'app';

    ngOnInit() {
        const connection = new signalR.HubConnectionBuilder()
            .withUrl("/chathub")
            .build();

        connection.on("receiveMessage", (username: string, message: string) => {
            console.log(username);
            console.log(message);
        });

        connection.start().then(() => {
            connection.send("sendMessage", "aaa", "aaaa")
                .then(() => console.log("done"));

        }).catch(err => document.write(err));
    }
}
0 голосов
/ 31 октября 2019

Похоже, что вы настроили аутентификацию на основе JWT на стороне сервера и не предоставляете токен для соединения SignalR. Попробуйте предоставить токен, используя accessTokenFactory:

this.hubConnection = new signalR.HubConnectionBuilder()
            .withUrl(`${environment.urlAddress}/chathub`, {
                accessTokenFactory: () => this.token
            })
            .build()
...