web-dev-qa-db-ja.com

asp.netコア3.0でSignalRを使用する方法

こんにちは、Signal Rに依存するasp.netコアプロジェクトに取り組んでいます。最後に、プロジェクトをasp.netコア2.2から3.0に更新したところ、Signal Rが機能しなくなりました。ドキュメントでは、すべてを構成しましたが(私は正しく考えます)、それでも機能しません。私たちは何を逃したのですか?

Asp.net Core 3.0 API

起動:

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

チャットハブ:

[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
Ties Theunissen

サーバー側でJWTベースの認証を構成しており、SignalR接続のトークンを提供していないようです。 accessTokenFactoryを使用してトークンを提供してみます。

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