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 });
}
}