120 lines
3.5 KiB
C#
120 lines
3.5 KiB
C#
using AmtScanner.Api.Data;
|
|
using AmtScanner.Api.Services;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using System.Net.WebSockets;
|
|
|
|
namespace AmtScanner.Api.Controllers;
|
|
|
|
/// <summary>
|
|
/// 屏幕流控制器 - 处理实时屏幕监控
|
|
/// </summary>
|
|
[ApiController]
|
|
[Route("api/screen-stream")]
|
|
public class ScreenStreamController : ControllerBase
|
|
{
|
|
private readonly ILogger<ScreenStreamController> _logger;
|
|
private readonly AppDbContext _db;
|
|
private readonly ScreenStreamProxyService _proxyService;
|
|
|
|
public ScreenStreamController(
|
|
ILogger<ScreenStreamController> logger,
|
|
AppDbContext db,
|
|
ScreenStreamProxyService proxyService)
|
|
{
|
|
_logger = logger;
|
|
_db = db;
|
|
_proxyService = proxyService;
|
|
}
|
|
|
|
/// <summary>
|
|
/// WebSocket 端点 - 代理到指定设备的屏幕流
|
|
/// </summary>
|
|
[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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// WebSocket 端点 - 直接通过 IP 连接
|
|
/// </summary>
|
|
[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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取支持屏幕流的在线设备列表
|
|
/// </summary>
|
|
[HttpGet("devices")]
|
|
public async Task<IActionResult> 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 });
|
|
}
|
|
}
|