Я перепробовал множество пакетов для установления соединения между клиентом 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);
})
}