Browse Source

建立跟web端通讯类型接口

develop
杨栋梁 3 years ago
parent
commit
dbc97d5bcf
  1. 8
      AX.WebDrillServer/AX.WebDrillServer.sln
  2. 14
      AX.WebDrillServer/Controllers/AccountsController.cs
  3. 8
      AX.WebDrillServer/Data/ApplicationDbContextSeed.cs
  4. 176
      AX.WebDrillServer/Hubs/FireDeductionHub.cs
  5. 21
      AX.WebDrillServer/Models/Room.cs
  6. 6
      AX.WebDrillServer/Program.cs
  7. 35
      AX.WebDrillServer/Services/FireDeductionHub/FireDeductionRoom.cs
  8. 14
      AX.WebDrillServer/Services/FireDeductionHub/FireDeductionUser.cs
  9. 11
      AX.WebDrillServer/Services/FireDeductionHub/RoomCreateDto.cs
  10. 79
      AX.WebDrillServer/Services/FireDeductionHub/RoomManager.cs

8
AX.WebDrillServer/AX.WebDrillServer.sln

@ -5,6 +5,8 @@ VisualStudioVersion = 17.3.32825.248
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AX.WebDrillServer", "AX.WebDrillServer.csproj", "{B594C541-C030-412E-8B89-D38C24765D2D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestHub", "..\TestHub\TestHub.csproj", "{4B962EF6-1C2A-4283-B21D-46E6C57DD8D2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -18,6 +20,12 @@ Global
{B594C541-C030-412E-8B89-D38C24765D2D}.Release|Any CPU.Build.0 = Release|Any CPU
{B594C541-C030-412E-8B89-D38C24765D2D}.Test|Any CPU.ActiveCfg = Test|Any CPU
{B594C541-C030-412E-8B89-D38C24765D2D}.Test|Any CPU.Build.0 = Test|Any CPU
{4B962EF6-1C2A-4283-B21D-46E6C57DD8D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4B962EF6-1C2A-4283-B21D-46E6C57DD8D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4B962EF6-1C2A-4283-B21D-46E6C57DD8D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4B962EF6-1C2A-4283-B21D-46E6C57DD8D2}.Release|Any CPU.Build.0 = Release|Any CPU
{4B962EF6-1C2A-4283-B21D-46E6C57DD8D2}.Test|Any CPU.ActiveCfg = Debug|Any CPU
{4B962EF6-1C2A-4283-B21D-46E6C57DD8D2}.Test|Any CPU.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

14
AX.WebDrillServer/Controllers/AccountsController.cs

@ -109,18 +109,16 @@ namespace AX.WebDrillServer.Controllers
}
}
/// <summary>
/// 登出
/// 登出系统。
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[AllowAnonymous]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[HttpPost("[action]")]
public async Task<ActionResult<UserDto>> SignOut([FromBody] UserForCreateDto dto)
[ProducesResponseType(StatusCodes.Status200OK)]
[HttpPost("SignOut")]
public ActionResult AccountSignOut()
{
throw new NotImplementedException();
//TODO: 把 JWT 放入黑名单,其它地方则验证黑名单,将来再处理
return Ok();
}
/// <summary>
/// 刷新令牌。

8
AX.WebDrillServer/Data/ApplicationDbContextSeed.cs

@ -72,15 +72,15 @@ namespace AX.WebDrillServer.Data
var org2 = new Organization()
{
Code = "1-1-1",
Name = "XXX队",
Level = OrganizationLevel.Battalion,
Name = "XXX队",
Level = OrganizationLevel.Brigade,
};
context.Organizations.Add(org2);
var org3 = new Organization()
{
Code = "1-1-1-1",
Name = "XXX队",
Level = OrganizationLevel.Brigade,
Name = "XXX队",
Level = OrganizationLevel.Battalion,
};
context.Organizations.Add(org3);
var org4 = new Organization()

176
AX.WebDrillServer/Hubs/FireDeductionHub.cs

@ -0,0 +1,176 @@
using AX.WebDrillServer.Data;
using AX.WebDrillServer.Extensions;
using AX.WebDrillServer.Middlewares.Jwts;
using AX.WebDrillServer.Models;
using AX.WebDrillServer.Services.FireDeductionHub;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using System.Collections.Concurrent;
using System.Security.Claims;
namespace AX.WebDrillServer.Hubs
{
//[Authorize]
public class FireDeductionHub : Hub
{
private readonly RoomManager roomManager;
private readonly ApplicationDbContext _dbContext;
private readonly ILogger<FireDeductionHub> _logger;
public FireDeductionHub(
ApplicationDbContext dbContext,
ILogger<FireDeductionHub> logger,
RoomManager roomManager)
{
_dbContext = dbContext;
_logger = logger;
this.roomManager = roomManager;
}
public async Task<FireDeductionRoom> CreateRoom(RoomCreateDto createInfo, FireDeductionUser user)
{
FireDeductionRoom room = new FireDeductionRoom();
room.Owner = createInfo.UserId;
room.RoomId = Guid.NewGuid().ToString();
room.RoomName = createInfo.RoomName;
room.Password = createInfo.RoomPassword;
room.Users.Add(user);
await Groups.AddToGroupAsync(user.ConnectionId, room.RoomId);
return room;
}
public async Task<bool> EnterRoom(string roomId, FireDeductionUser user, string? password = null)
{
bool result = false;
var room = roomManager.GetRoom(roomId);
if (room != null && room.Password == password)
{
if (!room.Users.Contains(user))
{
result = true;
}
else
{
throw new NotImplementedException("房间中已经存在该用户!");
}
}
else
{
throw new NotImplementedException("房间信息有误!");
}
return result;
}
public async Task<bool> LeaveRoom(string roomId, string userId)
{
bool result = false;
await Task.Run(() =>
{
var room = roomManager.GetRoom(roomId);
if (room != null)
{
var user = room.Users.FirstOrDefault(u => u.UserId == userId);
if (user != null)
{
room.Users.Remove(user);
if (room.Users.Count == 0)
{
//TODO:保持空房间xx分钟
}
}
else
{
throw new NotImplementedException("用户信息有误!");
}
}
else
{
throw new NotImplementedException("房间信息有误!");
}
});
return result;
}
public async Task RoomSendMessage(string RoomId, string Message)
{
await Clients.Group(RoomId).SendAsync(Message);
//TODO:保存数据
}
public async Task SendMessage(string user, string Message)
{
await Clients.All.SendAsync(Message);
//TODO:保存数据
}
public override async Task OnConnectedAsync()
{
try
{
var userId = Context.UserIdentifier;
var userName = Context.GetNameOfCurrentUser();
FireDeductionUser? user = roomManager.GetUser(userId!);
if (user != null)
{
user.Online = true;
var room = roomManager.GetRoomByUserId(user.UserId);
if (room != null)
{
//断线重连
}
}
else
{
user = new FireDeductionUser();
user.ConnectionId = Context.ConnectionId;
user.UserId = userId!;
user.UserName = userName!;
}
_logger.LogInformation("[{userId}][{name}] connected", userId, userName);
await base.OnConnectedAsync();
}
catch (Exception)
{
throw;
}
}
public override async Task OnDisconnectedAsync(Exception? exception)
{
try
{
var userId = Context.UserIdentifier;
var userName = Context.User?.FindFirstValue(JwtClaimTypes.Name);
if (userId == null) _logger.LogError("无效的 userId: [{userId}]!", userId);
if (userId != null)
{
var user = roomManager.GetUser(userId!);
if (user != null)
{
user.Online = false;
var room = roomManager.GetRoomByUserId(user.UserId);
if (room != null)
{
//断线
}
}
}
await base.OnDisconnectedAsync(exception);
_logger.LogInformation("[{userId}][{name}] 断开了连接", userId, userName);
}
catch (Exception)
{
throw;
}
}
}
}

21
AX.WebDrillServer/Models/Room.cs

@ -1,21 +0,0 @@
namespace AX.WebDrillServer.Models
{
/// <summary>
/// 房间表
/// </summary>
public class Room : EntityBase
{
/// <summary>
/// 密码
/// </summary>
public string? Password { get; set; }
/// <summary>
/// 所属
/// </summary>
public User? Owner { get; set; }
/// <summary>
/// 用户
/// </summary>
public ICollection<User>? Users { get; set; }
}
}

6
AX.WebDrillServer/Program.cs

@ -5,6 +5,7 @@ using AX.WebDrillServer.Extensions;
using AX.WebDrillServer.Hubs;
using AX.WebDrillServer.Middlewares;
using AX.WebDrillServer.Middlewares.Jwts;
using AX.WebDrillServer.Services.FireDeductionHub;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.AspNetCore.Mvc.Formatters;
@ -18,7 +19,7 @@ using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
const string ProductName = "Web服务器";
const string ProductName = "沙盘推演";
const string ProductVersion = "v1.0";
const string ApiVersion = "v1";
@ -108,7 +109,7 @@ builder.Services.AddAuthorization();
// Email Service
//builder.Services.AddSingleton<IEmailService, EmailService>();
builder.Services.AddSingleton<RoomManager>();
builder.Services.AddMemoryCache();
builder.Services
@ -271,5 +272,6 @@ app.MapControllers();
//app.MapHub<NotificationHub>("/hubs/notification");
//app.MapHub<TaskChatHub>("/hubs/taskchat");
app.MapHub<FireDeductionHub>("/hubs/FireDeductionHub");
app.Run();

35
AX.WebDrillServer/Services/FireDeductionHub/FireDeductionRoom.cs

@ -0,0 +1,35 @@
using Org.BouncyCastle.Asn1.X509;
namespace AX.WebDrillServer.Services.FireDeductionHub
{
public enum RoomState
{
= 0,
,
}
/// <summary>
/// 沙盘推演房间
/// </summary>
public class FireDeductionRoom
{
public string RoomId { get; set; } = null!;
public string RoomName { get; set; } = null!;
/// <summary>
/// 房间密码
/// </summary>
public string? Password;
public RoomState State { get; set; } = RoomState.;
/// <summary>
/// 房间最大人数
/// </summary>
public int MaxPersons = 100;
/// <summary>
/// 房间所属,默认是创建者
/// </summary>
public string Owner { get; set; } = null!;
public List<FireDeductionUser> Users { get; set; } = new List<FireDeductionUser>();
public Dictionary<DateTime, string>? FrameData { get; set; }
public Dictionary<DateTime, string>? EventData { get; set; }
}
}

14
AX.WebDrillServer/Services/FireDeductionHub/FireDeductionUser.cs

@ -0,0 +1,14 @@
namespace AX.WebDrillServer.Services.FireDeductionHub
{
/// <summary>
/// 沙盘推演用户
/// </summary>
public class FireDeductionUser
{
public string UserId { get; set; } = null!;
public string UserName { get; set; } = null!;
public bool Online { get; set; } = true;
public bool Left { get; set; }
public string ConnectionId { get; set; } = null!;
}
}

11
AX.WebDrillServer/Services/FireDeductionHub/RoomCreateDto.cs

@ -0,0 +1,11 @@
namespace AX.WebDrillServer.Services.FireDeductionHub
{
public class RoomCreateDto
{
public string UserId { get; set; } = null!;
public string? RoomPassword { get; set; }
public string RoomName { get; set; } = null!;
public int MaxPerson { get; set; } = 20;
}
}

79
AX.WebDrillServer/Services/FireDeductionHub/RoomManager.cs

@ -0,0 +1,79 @@
namespace AX.WebDrillServer.Services.FireDeductionHub
{
public class RoomManager
{
private List<FireDeductionRoom> fireDeductionRooms = new List<FireDeductionRoom>();
private List<FireDeductionUser> fireDeductionUsers = new List<FireDeductionUser>();
public FireDeductionRoom? GetRoom(string roomId)
{
lock (this)
{
return fireDeductionRooms.Where(r => r.RoomId == roomId).SingleOrDefault();
}
}
public FireDeductionUser? GetUser(string userId)
{
lock (this)
{
return fireDeductionUsers.Where(r => r.UserId == userId).SingleOrDefault();
}
}
public FireDeductionRoom? GetRoomByUserId(string userId)
{
lock (this)
{
return fireDeductionRooms.Where(r => r.Users.Where(u => u.UserId == userId).SingleOrDefault() != null).SingleOrDefault();
}
}
public void AddRoom(FireDeductionRoom room)
{
lock (this)
{
if (!fireDeductionRooms.Contains(room))
{
fireDeductionRooms.Add(room);
}
}
}
public void RemoveRoom(string roomId)
{
lock (this)
{
for (int i = 0; i < fireDeductionRooms.Count; i++)
{
if (fireDeductionRooms[i].RoomId == roomId)
{
fireDeductionRooms.RemoveAt(i);
}
}
}
}
public void AddUser(FireDeductionUser user)
{
lock (this)
{
if (!fireDeductionUsers.Contains(user))
{
fireDeductionUsers.Add(user);
}
}
}
public void RemoveUser(string userId)
{
lock (this)
{
for (int i = 0; i < fireDeductionUsers.Count; i++)
{
if (fireDeductionUsers[i].UserId == userId)
{
fireDeductionUsers.RemoveAt(i);
}
}
}
}
}
}
Loading…
Cancel
Save