Подключите клиент React js к SignalR - PullRequest
0 голосов
/ 05 апреля 2020

Я перепробовал множество пакетов для установления соединения между клиентом React и ASP. NET сервером signalR.

Я думаю, что может быть некоторая проблема с настройкой сервера signalR с использованием signalR для первого время.

. NET CORE Версия 2.2.

Пробные пакеты:

@microsoft/signalr
@aspnet/signalr
@aspnet/signalr-client

Класс запуска:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using BLL.Service.Mappings;
using BLL.Service.Services;
using DAL;
using DAL.Repositories;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using System.Text;
using Microsoft.IdentityModel.Tokens;
using WebApplication2.ExceptionHandler;
using Microsoft.Extensions.FileProviders;
using System.IO;
using WebApplication2.Controllers;
using BLL.Service.Hubs;

namespace WebApplication2
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }


        public void ConfigureServices(IServiceCollection services)
        {


            services.Configure<CookiePolicyOptions>(options =>
            {

                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.AddDistributedMemoryCache();
            services.AddAutoMapper(typeof(AutoMapperMappings).Assembly);
            services.AddDbContext<EfContext, ApplicationContext>();
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            services.AddHttpContextAccessor();


            services.AddAuthentication().AddSteam(options=> {
                options.ApplicationKey = "8F48B0D274523F0FA2252C995B2CBCA1";
                options.CallbackPath = "/Login/Steam";
                options.Authority = new Uri("https://steamcommunity.com/openid/");



            });


            services.AddCors(options =>
            {
                options.AddPolicy("AllowAll",
                    builder =>
                    {
                        builder
                        .AllowAnyOrigin()
                        .AllowAnyMethod()
                        .AllowAnyHeader()
                        .AllowCredentials();
                    });

            });
            services.AddSignalR();

            #region JWT
            var key = Encoding.ASCII.GetBytes(Configuration["JwtKey"]);
            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
                };
            });

            #endregion


            services.AddSingleton<IFileProvider>(
       new PhysicalFileProvider(Directory.GetCurrentDirectory()));
            services.AddScoped<RequestScope<EfContext>>(provider =>
            {
                var dbContext = provider.GetRequiredService<EfContext>();
                var scope = provider.GetRequiredService<RequestScope>();
                return new RequestScope<EfContext>(scope.ServiceProvider, dbContext, scope.Logger, scope.Mapper, scope.UserId);
            });
            services.AddScoped<RequestScope>(provider =>
            {
                var logger = provider.GetRequiredService<ILogger<Program>>();
                var context = provider.GetRequiredService<IHttpContextAccessor>();
                var claims = context.HttpContext.User.Claims;
                var userId = claims.FirstOrDefault(o => o.Type == "UserId")?.Value;

                var mapper = provider.GetRequiredService<IMapper>();

                return new RequestScope(provider, logger, mapper, userId);
            });
            services.AddMvc().AddJsonOptions(options =>
            {
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;

                //if (Environment.IsProduction())
                //{
                //    options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
                //    options.SerializerSettings.DefaultValueHandling = DefaultValueHandling.Ignore;
                //}
            });
            services.AddSession(options =>
            {
                options.Cookie.Name = "GSI Session";
                options.IdleTimeout = TimeSpan.FromHours(1);
                options.Cookie.IsEssential = true;

            });
            ConfigureRepositories(services);
            ConfigureAppServices(services);
        }

        private void ConfigureRepositories(IServiceCollection services)
        {
            services.AddScoped<IRoleRepository, RoleRepository>();
            services.AddScoped<ITeamRepository, TeamRepository>();
            services.AddScoped<IGameRepository, GameRepository>();
            services.AddScoped<IUserRepository, UserRepository>();
            services.AddScoped<IMatchRepository, MatchRepository>();
            services.AddScoped<IRoleRightRepository, RoleRightRepository>();
            services.AddScoped<IPlayerRepository, PlayerRepository>();
            services.AddScoped<IPlayerRequestRepository, PlayerRequestRepository>();
            services.AddScoped<IPlayerStatsRepository, PlayerStatsRepository>();
            services.AddScoped<IUserProfileRepository, UserProfileRepository>();
            services.AddScoped<ITeamPlayerRepository, TeamPlayerRepository>();
            services.AddScoped<IMatchDetailsRepository, MatchDetailsRepository>();
            services.AddScoped<IMatchRequestRepository, MatchRequestRepository>();
            services.AddScoped<IGameStateRepository, GameStateRepository>();

        }

        private void ConfigureAppServices(IServiceCollection services)
        {
            services.AddScoped<IRoleService, RoleService>();
            services.AddScoped<ITeamService, TeamService>();
            services.AddScoped<IGameService, GameService>();
            services.AddScoped<IUserService, UserService>();
            services.AddScoped<IMatchService, MatchService>();
            services.AddScoped<IRoleRightService, RoleRightService>();
            services.AddScoped<ILoginService, LoginService>();
            services.AddScoped<IPlayerService, PlayerService>();
            services.AddScoped<IPlayerRequestService, PlayerRequestService>();
            services.AddScoped<IPlayerStatsService, PlayerStatsService>();
            services.AddScoped<IUserProfileService, UserProfileService>();
            services.AddScoped<IGameStateService, GameStateService>();
            services.AddScoped<ITeamPlayersService, TeamPlayersService>();
            services.AddScoped<IMatchDetailsService, MatchDetailsService>();
            services.AddScoped<IMatchRequestService, MatchRequestService>();
            services.AddScoped<MatchHub>();
            // services.AddScoped<IHttpContextAccessor,HttpContextAccessor>();



        }





    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
            app.UseSignalR(routes =>
            {

                routes.MapHub<MatchHub>("/match");
            });
            app.UseMiddleware<ExceptionMiddleware>();

            app.UseCors("AllowAll");

            app.UseHttpsRedirection();
            app.UseAuthentication();
            app.UseSession();
            app.UseMvc();


    }
}
    }
MatchHub which is Hub:

    [EnableCors("AllowAll")]
    public class MatchHub : Hub
    {
    private readonly IHttpContextAccessor _httpContextAccessor;
    private readonly ITeamService _teamService;
    public MatchHub(IHttpContextAccessor httpContextAccessor,
             ITeamService teamService)
    {
            _httpContextAccessor = httpContextAccessor;
            _teamService = teamService;
        }

        public async Task CreateGroup(GameStates states)
        {
            var UserId = _httpContextAccessor.HttpContext.User.FindFirst(x => x.Type == "UserId")?.Value;


            var players = (await _teamService.Get(x => x.Include(team => team.TeamPlayers),
                x => x.TeamPlayers.Any(query => query.PlayerId == UserId)))
                .Values
                    .Select(x => new
                    {
                        PlayerIds = x.TeamPlayers.Select(player => player.PlayerId).ToList()

                    })
                        .Select(x => x.PlayerIds)?.FirstOrDefault();
            players.ForEach(async x =>
            {
                await Clients.Client(x).SendAsync("GameStates", states);
            });

        }

        private async Task<List<string>> UserGroupForATeam(int? teamId)
        => (await _teamService.Get(x => x.Include(team => team.TeamPlayers),
               x => x.Id == teamId))
               .Values
                   .Select(x => new
                   {
                       PlayerIds = x.TeamPlayers.Select(player => player.PlayerId).ToList()

                   })
                       .Select(x => x.PlayerIds)?.FirstOrDefault();

        public async Task MatchRequest(object obj, int? SenderTeam, int? ReceiverTeamId)
        {
            var groupOfUser = await UserGroupForATeam(ReceiverTeamId);
            foreach (var item in groupOfUser)
            {
                await Clients.Client(item).SendAsync("MatchRequest", obj);
            }


        }
        public async Task TeamJoinRequest (object obj, string connectionId)
        {
           await Clients.Client(connectionId).SendAsync("TeamJoinRequests", obj);
        }
        public async Task GameState(GameStates states)
        {
            await Clients.Group("Team").SendAsync("states", states);
        }
        //public  async Task Send(string connectionId,object data,int matchId)
        //{
        //    var State = (await _gameStateService.Get(x => x.MatchId ==           matchId)).Values.LastOrDefault().GameStateJSON;
        //    var GameState = new GameState(State);
        //    await Clients.Client(connectionId).SendAsync("Send",data);
        //}
    }
    }

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

     function Invoke()
      {

      //  let connection  = new signalr.HubConnection('http://localhost:4000/match',)
        let connection = new signalr.HubConnectionBuilder().withUrl('http://localhost:4000/match').build();
        connection.start()
        .then(() => console.log('Connection started!'))
            .catch(err => console.log(err));
          connection.on('MatchRequest',data=>{
            alert(data);
          })

      } 
...