190 lines
6.2 KiB
C#
190 lines
6.2 KiB
C#
using System.Net.WebSockets;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Linq;
|
|
using YD_YiLu.Api.WebSockets;
|
|
using YD_YiLu.Commons.Dto.Running;
|
|
|
|
namespace YD_YiLu.Api.Controllers
|
|
{
|
|
/// <summary>
|
|
/// 阳光跑接口。
|
|
/// </summary>
|
|
[AllowAnonymous]
|
|
public class RunningController : ControllerBase
|
|
{
|
|
private readonly ICameraDeviceSocketRegistry _registry;
|
|
private readonly ILogger<RunningController> _logger;
|
|
|
|
public RunningController(ICameraDeviceSocketRegistry registry, ILogger<RunningController> logger)
|
|
{
|
|
_registry = registry;
|
|
_logger = logger;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 跑道人员变更状态。
|
|
/// </summary>
|
|
[HttpPost]
|
|
[Route("/running/result/stage")]
|
|
public object ResultStage([FromBody] RunningStageRequestDto dto)
|
|
{
|
|
_logger.LogInformation(
|
|
"Running stage changed. DeviceSerial: {DeviceSerial}, UserCount: {UserCount}",
|
|
dto?.DeviceSerial,
|
|
dto?.RunUserList?.Count ?? 0);
|
|
|
|
return new { };
|
|
}
|
|
|
|
/// <summary>
|
|
/// 平台指定用户下发人脸通知(旧)。
|
|
/// </summary>
|
|
[HttpPost]
|
|
[Route("/station:user:push")]
|
|
public async Task<object> StationUserPush([FromBody] JObject body, [FromQuery] string deviceSerial = "")
|
|
{
|
|
return await SendSocketMessageAsync("station:user:push", body, deviceSerial);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 平台下发人脸通知。
|
|
/// </summary>
|
|
[HttpPost]
|
|
[Route("/station:remind")]
|
|
public async Task<object> StationRemind([FromBody] JObject body, [FromQuery] string deviceSerial = "")
|
|
{
|
|
return await SendSocketMessageAsync("station:remind", body, deviceSerial);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 跑步小组重启。
|
|
/// </summary>
|
|
[HttpPost]
|
|
[Route("/running:group:restart")]
|
|
public async Task<object> RunningGroupRestart([FromBody] JObject body, [FromQuery] string deviceSerial = "")
|
|
{
|
|
return await SendSocketMessageAsync("running:group:restart", body, deviceSerial);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 跑步小组推送。
|
|
/// </summary>
|
|
[HttpPost]
|
|
[Route("/running:group:push")]
|
|
public async Task<object> RunningGroupPush([FromBody] JObject body, [FromQuery] string deviceSerial = "")
|
|
{
|
|
return await SendSocketMessageAsync("running:group:push", body, deviceSerial);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 跑步小组自动分组。
|
|
/// </summary>
|
|
[HttpPost]
|
|
[Route("/running:group:auto")]
|
|
public async Task<object> RunningGroupAuto([FromBody] JObject body, [FromQuery] string deviceSerial = "")
|
|
{
|
|
return await SendSocketMessageAsync("running:group:auto", body, deviceSerial);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设备指令。
|
|
/// </summary>
|
|
[HttpPost]
|
|
[Route("/device:instruct")]
|
|
public async Task<object> DeviceInstruct([FromBody] JObject body, [FromQuery] string deviceSerial = "")
|
|
{
|
|
return await SendSocketMessageAsync("device:instruct", body, deviceSerial);
|
|
}
|
|
|
|
private async Task<object> SendSocketMessageAsync(string request, JObject body, string deviceSerial)
|
|
{
|
|
body ??= new JObject();
|
|
|
|
var serial = FirstNotEmpty(deviceSerial, FindString(body, "serialNumber"), FindString(body, "deviceSerial"));
|
|
if (string.IsNullOrWhiteSpace(serial))
|
|
{
|
|
return new
|
|
{
|
|
success = false,
|
|
message = "deviceSerial不能为空"
|
|
};
|
|
}
|
|
|
|
if (!_registry.TryGet(serial, out var socket) || socket.State != WebSocketState.Open)
|
|
{
|
|
return new
|
|
{
|
|
success = false,
|
|
serialNumber = serial,
|
|
message = "设备不在线"
|
|
};
|
|
}
|
|
|
|
var message = NormalizeSocketMessage(request, body);
|
|
await CameraDeviceWebSocketHandler.SendAsync(
|
|
socket,
|
|
message.ToString(Formatting.None),
|
|
HttpContext.RequestAborted);
|
|
|
|
_logger.LogInformation("Running socket message sent. Request: {Request}, SerialNumber: {SerialNumber}", request, serial);
|
|
|
|
return new
|
|
{
|
|
success = true,
|
|
serialNumber = serial
|
|
};
|
|
}
|
|
|
|
private static JObject NormalizeSocketMessage(string request, JObject body)
|
|
{
|
|
var message = (JObject)body.DeepClone();
|
|
|
|
if (string.IsNullOrWhiteSpace(message["msgId"]?.ToString()))
|
|
message["msgId"] = Guid.NewGuid().ToString("N");
|
|
|
|
message["request"] = request;
|
|
message["code"] ??= 0;
|
|
message["msg"] ??= "";
|
|
message["data"] ??= new JObject();
|
|
|
|
return message;
|
|
}
|
|
|
|
private static string FirstNotEmpty(params string[] values)
|
|
{
|
|
return values.FirstOrDefault(x => !string.IsNullOrWhiteSpace(x)) ?? "";
|
|
}
|
|
|
|
private static string FindString(JToken token, string name)
|
|
{
|
|
if (token == null)
|
|
return "";
|
|
|
|
if (token.Type == JTokenType.Object)
|
|
{
|
|
var obj = (JObject)token;
|
|
foreach (var property in obj.Properties())
|
|
{
|
|
if (string.Equals(property.Name, name, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
var value = property.Value?.ToString();
|
|
if (!string.IsNullOrWhiteSpace(value))
|
|
return value;
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (var child in token.Children())
|
|
{
|
|
var value = FindString(child, name);
|
|
if (!string.IsNullOrWhiteSpace(value))
|
|
return value;
|
|
}
|
|
|
|
return "";
|
|
}
|
|
}
|
|
}
|