fix: 修复数据库与SignalR无法连接的问题

This commit is contained in:
SikongJueluo 2025-08-15 13:02:56 +08:00
parent 6fa7fffa7f
commit a00cc84e48
No known key found for this signature in database
20 changed files with 78 additions and 123 deletions

View File

@ -86,7 +86,8 @@ try
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) && (
path.StartsWithSegments("/hubs/JtagHub") ||
path.StartsWithSegments("/hubs/ProgressHub")
path.StartsWithSegments("/hubs/ProgressHub") ||
path.StartsWithSegments("/hubs/DigitalTubesHub")
))
{
// Read the token out of the query string
@ -172,12 +173,6 @@ try
options.OperationProcessors.Add(new OperationSecurityScopeProcessor("Bearer"));
});
// 添加数据库资源管理器服务
builder.Services.AddScoped<Database.AppDataConnection>();
builder.Services.AddScoped<Database.UserManager>();
builder.Services.AddScoped<Database.ResourceManager>();
builder.Services.AddScoped<Database.ExamManager>();
// 添加 HTTP 视频流服务
builder.Services.AddSingleton<HttpVideoStreamService>();
builder.Services.AddHostedService(provider => provider.GetRequiredService<HttpVideoStreamService>());
@ -257,9 +252,9 @@ try
// Router
app.MapControllers();
app.MapHub<server.Hubs.JtagHub>("hubs/JtagHub");
app.MapHub<server.Hubs.ProgressHub>("hubs/ProgressHub");
app.MapHub<server.Hubs.DigitalTubesHub>("hubs/DigitalTubesHub");
app.MapHub<server.Hubs.JtagHub>("/hubs/JtagHub");
app.MapHub<server.Hubs.ProgressHub>("/hubs/ProgressHub");
app.MapHub<server.Hubs.DigitalTubesHub>("/hubs/DigitalTubesHub");
// Setup Program
MsgBus.Init();

View File

@ -18,16 +18,11 @@ public class DataController : ControllerBase
{
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private readonly Database.UserManager _userManager;
private readonly Database.UserManager _userManager = new();
// 固定的实验板IP,端口,MAC地址
private const string BOARD_IP = "169.254.109.0";
public DataController(Database.UserManager userManager)
{
_userManager = userManager;
}
/// <summary>
/// 获取本机IP地址优先选择与实验板同网段的IP
/// </summary>

View File

@ -15,12 +15,7 @@ public class DebuggerController : ControllerBase
{
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private readonly Database.UserManager _userManager;
public DebuggerController(Database.UserManager userManager)
{
this._userManager = userManager;
}
private readonly Database.UserManager _userManager = new();
/// <summary>
/// 获取当前用户绑定的调试器实例

View File

@ -15,19 +15,9 @@ public class ExamController : ControllerBase
{
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private readonly ExamManager _examManager;
private readonly ResourceManager _resourceManager;
private readonly UserManager _userManager;
public ExamController(
ExamManager examManager,
ResourceManager resourceManager,
UserManager userManager)
{
_examManager = examManager;
_resourceManager = resourceManager;
_userManager = userManager;
}
private readonly ExamManager _examManager = new();
private readonly ResourceManager _resourceManager = new();
private readonly UserManager _userManager = new();
/// <summary>
/// 获取所有实验列表

View File

@ -14,12 +14,11 @@ public class HdmiVideoStreamController : ControllerBase
private readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private readonly HttpHdmiVideoStreamService _videoStreamService;
private readonly Database.UserManager _userManager;
private readonly Database.UserManager _userManager = new();
public HdmiVideoStreamController(HttpHdmiVideoStreamService videoStreamService, Database.UserManager userManager)
public HdmiVideoStreamController(HttpHdmiVideoStreamService videoStreamService)
{
_videoStreamService = videoStreamService;
_userManager = userManager;
}
// 管理员获取所有板子的 endpoints

View File

@ -17,17 +17,14 @@ public class JtagController : ControllerBase
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private readonly ProgressTrackerService _tracker;
private readonly UserManager _userManager;
private readonly ResourceManager _resourceManager;
private readonly UserManager _userManager = new();
private readonly ResourceManager _resourceManager = new();
private const string BITSTREAM_PATH = "bitstream/Jtag";
public JtagController(
ProgressTrackerService tracker, UserManager userManager, ResourceManager resourceManager)
public JtagController(ProgressTrackerService tracker)
{
_tracker = tracker;
_userManager = userManager;
_resourceManager = resourceManager;
}
/// <summary>

View File

@ -15,12 +15,7 @@ public class LogicAnalyzerController : ControllerBase
{
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private readonly Database.UserManager _userManager;
public LogicAnalyzerController(Database.UserManager userManager)
{
_userManager = userManager;
}
private readonly Database.UserManager _userManager = new();
/// <summary>
/// 获取逻辑分析仪实例

View File

@ -15,12 +15,7 @@ public class OscilloscopeApiController : ControllerBase
{
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private readonly Database.UserManager _userManager;
public OscilloscopeApiController(Database.UserManager userManager)
{
_userManager = userManager;
}
private readonly Database.UserManager _userManager = new();
/// <summary>
/// 获取示波器实例

View File

@ -15,14 +15,8 @@ public class ResourceController : ControllerBase
{
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private readonly UserManager _userManager;
private readonly ResourceManager _resourceManager;
public ResourceController(UserManager userManager, ResourceManager resourceManager)
{
_userManager = userManager;
_resourceManager = resourceManager;
}
private readonly UserManager _userManager = new();
private readonly ResourceManager _resourceManager = new();
/// <summary>
/// 添加资源(文件上传)

View File

@ -18,7 +18,7 @@ public class VideoStreamController : ControllerBase
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private readonly HttpVideoStreamService _videoStreamService;
private readonly Database.UserManager _userManager;
private readonly Database.UserManager _userManager = new();
public class AvailableResolutionsResponse
{
@ -32,13 +32,10 @@ public class VideoStreamController : ControllerBase
/// 初始化HTTP视频流控制器
/// </summary>
/// <param name="videoStreamService">HTTP视频流服务</param>
/// <param name="userManager">用户管理服务</param>
public VideoStreamController(
HttpVideoStreamService videoStreamService, Database.UserManager userManager)
public VideoStreamController(HttpVideoStreamService videoStreamService)
{
logger.Info("创建VideoStreamController命名空间{Namespace}", this.GetType().Namespace);
_videoStreamService = videoStreamService;
_userManager = userManager;
}
private Optional<string> TryGetBoardId()

View File

@ -8,12 +8,7 @@ public class ExamManager
{
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private readonly AppDataConnection _db;
public ExamManager(AppDataConnection db)
{
this._db = db;
}
private AppDataConnection _db = new();
/// <summary>
/// 创建新实验

View File

@ -9,12 +9,7 @@ public class ResourceManager
{
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private readonly AppDataConnection _db;
public ResourceManager(AppDataConnection db)
{
this._db = db;
}
private readonly AppDataConnection _db = new();
/// <summary>
/// 根据文件扩展名获取MIME类型

View File

@ -8,12 +8,7 @@ public class UserManager
{
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private readonly AppDataConnection _db;
public UserManager(AppDataConnection db)
{
this._db = db;
}
private readonly AppDataConnection _db = new();
/// <summary>
/// 添加一个新的用户到数据库

View File

@ -16,6 +16,7 @@ public interface IDigitalTubesHub
Task<bool> StartScan();
Task<bool> StopScan();
Task<bool> SetFrequency(int frequency);
Task<DigitalTubeTaskStatus> GetStatus();
}
[Receiver]
@ -24,7 +25,20 @@ public interface IDigitalTubesReceiver
Task OnReceive(byte[] data);
}
class DigitalTubeInfo
[TranspilationSource]
public class DigitalTubeTaskStatus
{
public int Frequency { get; set; } = 100;
public bool IsRunning { get; set; } = false;
public DigitalTubeTaskStatus(DigitalTubeInfo info)
{
Frequency = info.Frequency;
IsRunning = info.IsRunning;
}
}
public class DigitalTubeInfo
{
public string ClientID { get; set; }
public SevenDigitalTubesCtrl TubeClient { get; set; }
@ -46,16 +60,13 @@ public class DigitalTubesHub : Hub<IDigitalTubesReceiver>, IDigitalTubesHub
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private readonly IHubContext<DigitalTubesHub, IDigitalTubesReceiver> _hubContext;
private readonly Database.UserManager _userManager;
private readonly Database.UserManager _userManager = new();
private ConcurrentDictionary<string, DigitalTubeInfo> _infoDict = new();
public DigitalTubesHub(
IHubContext<DigitalTubesHub, IDigitalTubesReceiver> hubContext,
Database.UserManager userManager)
public DigitalTubesHub(IHubContext<DigitalTubesHub, IDigitalTubesReceiver> hubContext)
{
_hubContext = hubContext;
_userManager = userManager;
}
private Optional<Database.Board> TryGetBoard()
@ -172,8 +183,8 @@ public class DigitalTubesHub : Hub<IDigitalTubesReceiver>, IDigitalTubesHub
{
try
{
if (frequency < 1 || frequency > 1000)
throw new ArgumentException("Frequency must be between 1 and 1000");
if (frequency < 1 || frequency > 1000) return Task.FromException<bool>(
new ArgumentException("Frequency must be between 1 and 1000"));
var board = TryGetBoard().OrThrow(() => new Exception("Board not found"));
if (_infoDict.GetOrAdd(
@ -194,4 +205,29 @@ public class DigitalTubesHub : Hub<IDigitalTubesReceiver>, IDigitalTubesHub
return Task.FromResult(false);
}
}
public Task<DigitalTubeTaskStatus> GetStatus()
{
try
{
var board = TryGetBoard().OrThrow(() => new Exception("Board not found"));
if (_infoDict.GetOrAdd(
board.ID.ToString(),
(_) => new DigitalTubeInfo(
Context.ConnectionId,
new SevenDigitalTubesCtrl(board.IpAddr, board.Port, 2))
) is DigitalTubeInfo info)
{
return Task.FromResult(new DigitalTubeTaskStatus(info));
}
return Task.FromException<DigitalTubeTaskStatus>(new ArgumentException("Wrong argument"));
}
catch (Exception ex)
{
logger.Error(ex, "Failed to get status");
return Task.FromException<DigitalTubeTaskStatus>(new Exception("Failed to get status"));
}
}
}

View File

@ -30,15 +30,14 @@ public class JtagHub : Hub<IJtagReceiver>, IJtagHub
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private readonly IHubContext<JtagHub, IJtagReceiver> _hubContext;
private readonly Database.UserManager _userManager;
private readonly Database.UserManager _userManager = new();
private static ConcurrentDictionary<string, int> FreqTable = new();
private static ConcurrentDictionary<string, CancellationTokenSource> CancellationTokenSourceTable = new();
public JtagHub(IHubContext<JtagHub, IJtagReceiver> hubContext, Database.UserManager userManager)
public JtagHub(IHubContext<JtagHub, IJtagReceiver> hubContext)
{
_hubContext = hubContext;
_userManager = userManager;
}
private Optional<Peripherals.JtagClient.Jtag> GetJtagClient(string userName)

View File

@ -42,7 +42,7 @@ public class SevenDigitalTubesCtrl
if (num < 0 || num > 31)
throw new ArgumentOutOfRangeException(nameof(num), "Tube number must be between 0 and 31");
var ret = await UDPClientPool.ReadAddr(
var ret = await UDPClientPool.ReadAddrByte(
this.ep, this.taskID, SevenDigitalTubesAddr.BASE + (UInt32)num, this.timeout);
if (!ret.IsSuccessful)
{

View File

@ -26,17 +26,10 @@ public class HttpHdmiVideoStreamService : BackgroundService
{
private readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private readonly IServiceProvider _serviceProvider;
private HttpListener? _httpListener;
private readonly int _serverPort = 4322;
private readonly ConcurrentDictionary<string, HdmiVideoStreamClient> _clientDict = new();
public HttpHdmiVideoStreamService(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public override async Task StartAsync(CancellationToken cancellationToken)
{
_httpListener = new HttpListener();
@ -124,8 +117,7 @@ public class HttpHdmiVideoStreamService : BackgroundService
{
if (_clientDict.TryGetValue(boardId, out var client)) return client;
using var scope = _serviceProvider.CreateScope();
var userManager = scope.ServiceProvider.GetRequiredService<Database.UserManager>();
var userManager = new Database.UserManager();
var boardRet = userManager.GetBoardByID(Guid.Parse(boardId));
if (!boardRet.IsSuccessful || !boardRet.Value.HasValue)
@ -362,8 +354,7 @@ public class HttpHdmiVideoStreamService : BackgroundService
/// <returns>返回所有可用的HDMI视频流终端点列表</returns>
public List<HdmiVideoStreamEndpoint>? GetAllVideoEndpoints()
{
using var scope = _serviceProvider.CreateScope();
var userManager = scope.ServiceProvider.GetRequiredService<Database.UserManager>();
var userManager = new Database.UserManager();
var boards = userManager.GetAllBoard();
if (boards == null)

View File

@ -95,8 +95,6 @@ public class HttpVideoStreamService : BackgroundService
{
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private readonly IServiceProvider _serviceProvider;
private HttpListener? _httpListener;
private readonly int _serverPort = 4321;
@ -109,11 +107,6 @@ public class HttpVideoStreamService : BackgroundService
private readonly object _usbCameraLock = new object();
#endif
public HttpVideoStreamService(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
private Optional<VideoStreamClient> TryGetClient(string boardId)
{
if (_clientDict.TryGetValue(boardId, out var client))
@ -131,8 +124,7 @@ public class HttpVideoStreamService : BackgroundService
return client;
}
using var scope = _serviceProvider.CreateScope();
var userManager = scope.ServiceProvider.GetRequiredService<Database.UserManager>();
var userManager = new Database.UserManager();
var boardRet = userManager.GetBoardByID(Guid.Parse(boardId));
if (!boardRet.IsSuccessful || !boardRet.Value.HasValue)

View File

@ -229,11 +229,11 @@ public class UDPClientPool
public static async ValueTask<Result<RecvDataPackage>> ReadAddr(
IPEndPoint endPoint, int taskID, uint devAddr, int dataLength, int timeout = 1000)
{
if (dataLength <= 0)
return new(new ArgumentException("Data length must be greater than 0"));
if (dataLength <= 0) return new(new ArgumentException(
$"Data length must be greater than 0, instead of {dataLength}"));
if (dataLength > 255)
return new(new ArgumentException("Data length must be less than or equal to 255"));
if (dataLength > 255) return new(new ArgumentException(
$"Data length must be less than or equal to 255, instead of {dataLength}"));
var ret = false;
var opts = new SendAddrPackOptions()