using AmtScanner.Api.Data; using AmtScanner.Api.Services; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using System.Net.WebSockets; namespace AmtScanner.Api.Controllers; /// /// 屏幕流控制器 - 处理实时屏幕监控 /// [ApiController] [Route("api/screen-stream")] public class ScreenStreamController : ControllerBase { private readonly ILogger _logger; private readonly AppDbContext _db; private readonly ScreenStreamProxyService _proxyService; public ScreenStreamController( ILogger logger, AppDbContext db, ScreenStreamProxyService proxyService) { _logger = logger; _db = db; _proxyService = proxyService; } /// /// WebSocket 端点 - 代理到指定设备的屏幕流 /// [HttpGet("ws/{uuid}")] public async Task GetScreenStream(string uuid) { if (!HttpContext.WebSockets.IsWebSocketRequest) { HttpContext.Response.StatusCode = 400; await HttpContext.Response.WriteAsync("需要 WebSocket 连接"); return; } // 查找设备 var device = await _db.AgentDevices_new.FirstOrDefaultAsync(d => d.Uuid == uuid); if (device == null) { HttpContext.Response.StatusCode = 404; await HttpContext.Response.WriteAsync("设备不存在"); return; } if (string.IsNullOrEmpty(device.IpAddress)) { HttpContext.Response.StatusCode = 400; await HttpContext.Response.WriteAsync("设备 IP 地址未知"); return; } // 接受 WebSocket 连接 using var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync(); _logger.LogInformation("客户端请求屏幕流: {Uuid} ({Ip})", uuid, device.IpAddress); // 代理到 Agent await _proxyService.ProxyScreenStreamAsync( webSocket, device.IpAddress, 9100, // Agent 默认端口 HttpContext.RequestAborted); } /// /// WebSocket 端点 - 直接通过 IP 连接 /// [HttpGet("ws/ip/{ip}")] public async Task GetScreenStreamByIp(string ip, [FromQuery] int port = 9100) { if (!HttpContext.WebSockets.IsWebSocketRequest) { HttpContext.Response.StatusCode = 400; await HttpContext.Response.WriteAsync("需要 WebSocket 连接"); return; } // 接受 WebSocket 连接 using var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync(); _logger.LogInformation("客户端请求屏幕流: {Ip}:{Port}", ip, port); // 代理到 Agent await _proxyService.ProxyScreenStreamAsync( webSocket, ip, port, HttpContext.RequestAborted); } /// /// 获取支持屏幕流的在线设备列表 /// [HttpGet("devices")] public async Task GetStreamableDevices() { var devices = await _db.AgentDevices_new .Where(d => d.IsOnline) .Select(d => new { d.Uuid, d.Hostname, d.IpAddress, d.CurrentUser, d.LastReportAt, StreamPort = 9100 }) .ToListAsync(); return Ok(new { code = 0, data = devices }); } }