7 changed files with 845 additions and 3 deletions
@ -0,0 +1,213 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using LTEMvcApp.Models; |
|||
using LTEMvcApp.Services; |
|||
using Microsoft.Extensions.Logging; |
|||
|
|||
namespace LTEMvcApp.Controllers |
|||
{ |
|||
/// <summary>
|
|||
/// IP组管理控制器 - 负责IP组网络启动、停止和Key管理
|
|||
/// </summary>
|
|||
[ApiController] |
|||
[Route("api/[controller]")]
|
|||
public class IpGroupController : ControllerBase |
|||
{ |
|||
private readonly HttpClientService _httpClientService; |
|||
private readonly ILogger<IpGroupController> _logger; |
|||
|
|||
// 存储IP组的Key配置
|
|||
private static readonly Dictionary<string, string> _ipGroupKeys = new(); |
|||
|
|||
public IpGroupController(HttpClientService httpClientService, ILogger<IpGroupController> logger) |
|||
{ |
|||
_httpClientService = httpClientService; |
|||
_logger = logger; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 保存IP组Key配置
|
|||
/// </summary>
|
|||
/// <param name="request">IP组Key请求</param>
|
|||
/// <returns>操作结果</returns>
|
|||
[HttpPost("key")] |
|||
public ActionResult SaveIpGroupKey([FromBody] IpGroupKeyRequest request) |
|||
{ |
|||
if (string.IsNullOrEmpty(request.Ip)) |
|||
return BadRequest("IP地址不能为空"); |
|||
|
|||
_ipGroupKeys[request.Ip] = request.Key ?? string.Empty; |
|||
_logger.LogInformation("保存IP组Key: {Ip} -> {Key}", request.Ip, request.Key); |
|||
|
|||
return Ok(new { message = "IP组Key保存成功" }); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 启动IP组网络
|
|||
/// </summary>
|
|||
/// <param name="request">启动网络请求</param>
|
|||
/// <returns>操作结果</returns>
|
|||
[HttpPost("start")] |
|||
public async Task<ActionResult> StartIpGroup([FromBody] StartIpGroupRequest request) |
|||
{ |
|||
if (string.IsNullOrEmpty(request.Ip)) |
|||
return BadRequest("IP地址不能为空"); |
|||
|
|||
if (string.IsNullOrEmpty(request.Port)) |
|||
return BadRequest("端口不能为空"); |
|||
|
|||
// 检查Key是否已配置
|
|||
if (!_ipGroupKeys.TryGetValue(request.Ip, out var key) || string.IsNullOrEmpty(key)) |
|||
return BadRequest("请先配置网络Key"); |
|||
|
|||
try |
|||
{ |
|||
var apiUrl = $"http://{request.Ip}:{request.Port}/api/v1/CellularNetwork/start"; |
|||
var command = new StartCellularNetworkCommand { Key = key }; |
|||
|
|||
_logger.LogInformation("启动IP组网络: {Ip}:{Port}, Key: {Key}", request.Ip, request.Port, key); |
|||
|
|||
var response = await _httpClientService.PostJsonAsync(apiUrl, command); |
|||
|
|||
_logger.LogInformation("IP组网络启动成功: {Response}", response); |
|||
return Ok(new { message = "网络启动成功", response }); |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
_logger.LogError(ex, "启动IP组网络失败: {Ip}:{Port}", request.Ip, request.Port); |
|||
return BadRequest($"启动网络失败: {ex.Message}"); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 停止IP组网络
|
|||
/// </summary>
|
|||
/// <param name="request">停止网络请求</param>
|
|||
/// <returns>操作结果</returns>
|
|||
[HttpPost("stop")] |
|||
public async Task<ActionResult> StopIpGroup([FromBody] StopIpGroupRequest request) |
|||
{ |
|||
if (string.IsNullOrEmpty(request.Ip)) |
|||
return BadRequest("IP地址不能为空"); |
|||
|
|||
if (string.IsNullOrEmpty(request.Port)) |
|||
return BadRequest("端口不能为空"); |
|||
|
|||
// 检查Key是否已配置
|
|||
if (!_ipGroupKeys.TryGetValue(request.Ip, out var key) || string.IsNullOrEmpty(key)) |
|||
return BadRequest("请先配置网络Key"); |
|||
|
|||
try |
|||
{ |
|||
var apiUrl = $"http://{request.Ip}:{request.Port}/api/v1/CellularNetwork/stop"; |
|||
var command = new StopCellularNetworkCommand { Key = key }; |
|||
|
|||
_logger.LogInformation("停止IP组网络: {Ip}:{Port}, Key: {Key}", request.Ip, request.Port, key); |
|||
|
|||
var response = await _httpClientService.PostJsonAsync(apiUrl, command); |
|||
|
|||
_logger.LogInformation("IP组网络停止成功: {Response}", response); |
|||
return Ok(new { message = "网络停止成功", response }); |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
_logger.LogError(ex, "停止IP组网络失败: {Ip}:{Port}", request.Ip, request.Port); |
|||
return BadRequest($"停止网络失败: {ex.Message}"); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 获取IP组Key配置
|
|||
/// </summary>
|
|||
/// <param name="ip">IP地址</param>
|
|||
/// <returns>Key配置</returns>
|
|||
[HttpGet("key/{ip}")] |
|||
public ActionResult GetIpGroupKey(string ip) |
|||
{ |
|||
if (string.IsNullOrEmpty(ip)) |
|||
return BadRequest("IP地址不能为空"); |
|||
|
|||
var key = _ipGroupKeys.TryGetValue(ip, out var value) ? value : string.Empty; |
|||
return Ok(new { ip, key }); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 获取所有IP组Key配置
|
|||
/// </summary>
|
|||
/// <returns>所有IP组Key配置</returns>
|
|||
[HttpGet("keys")] |
|||
public ActionResult GetAllIpGroupKeys() |
|||
{ |
|||
return Ok(_ipGroupKeys); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 删除IP组Key配置
|
|||
/// </summary>
|
|||
/// <param name="ip">IP地址</param>
|
|||
/// <returns>操作结果</returns>
|
|||
[HttpDelete("key/{ip}")] |
|||
public ActionResult DeleteIpGroupKey(string ip) |
|||
{ |
|||
if (string.IsNullOrEmpty(ip)) |
|||
return BadRequest("IP地址不能为空"); |
|||
|
|||
if (_ipGroupKeys.Remove(ip)) |
|||
{ |
|||
_logger.LogInformation("删除IP组Key: {Ip}", ip); |
|||
return Ok(new { message = "IP组Key删除成功" }); |
|||
} |
|||
else |
|||
{ |
|||
return NotFound($"未找到IP地址为 {ip} 的Key配置"); |
|||
} |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// IP组Key请求
|
|||
/// </summary>
|
|||
public class IpGroupKeyRequest |
|||
{ |
|||
/// <summary>
|
|||
/// IP地址
|
|||
/// </summary>
|
|||
public string Ip { get; set; } = string.Empty; |
|||
|
|||
/// <summary>
|
|||
/// Key值
|
|||
/// </summary>
|
|||
public string? Key { get; set; } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 启动IP组请求
|
|||
/// </summary>
|
|||
public class StartIpGroupRequest |
|||
{ |
|||
/// <summary>
|
|||
/// IP地址
|
|||
/// </summary>
|
|||
public string Ip { get; set; } = string.Empty; |
|||
|
|||
/// <summary>
|
|||
/// 端口
|
|||
/// </summary>
|
|||
public string Port { get; set; } = string.Empty; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 停止IP组请求
|
|||
/// </summary>
|
|||
public class StopIpGroupRequest |
|||
{ |
|||
/// <summary>
|
|||
/// IP地址
|
|||
/// </summary>
|
|||
public string Ip { get; set; } = string.Empty; |
|||
|
|||
/// <summary>
|
|||
/// 端口
|
|||
/// </summary>
|
|||
public string Port { get; set; } = string.Empty; |
|||
} |
|||
} |
@ -0,0 +1,13 @@ |
|||
namespace LTEMvcApp.Models |
|||
{ |
|||
/// <summary>
|
|||
/// 启动蜂窝网络命令
|
|||
/// </summary>
|
|||
public class StartCellularNetworkCommand |
|||
{ |
|||
/// <summary>
|
|||
/// 网络配置键
|
|||
/// </summary>
|
|||
public string Key { get; set; } = string.Empty; |
|||
} |
|||
} |
@ -0,0 +1,13 @@ |
|||
namespace LTEMvcApp.Models |
|||
{ |
|||
/// <summary>
|
|||
/// 停止蜂窝网络命令
|
|||
/// </summary>
|
|||
public class StopCellularNetworkCommand |
|||
{ |
|||
/// <summary>
|
|||
/// 网络接口名称
|
|||
/// </summary>
|
|||
public string Key { get; set; } = string.Empty; |
|||
} |
|||
} |
@ -0,0 +1,301 @@ |
|||
using System; |
|||
using System.Net.Http; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.Logging; |
|||
using Newtonsoft.Json; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace LTEMvcApp.Services |
|||
{ |
|||
/// <summary>
|
|||
/// HTTP客户端服务 - 提供HTTP请求功能
|
|||
/// </summary>
|
|||
public class HttpClientService |
|||
{ |
|||
private readonly HttpClient _httpClient; |
|||
private readonly ILogger<HttpClientService> _logger; |
|||
|
|||
public HttpClientService(HttpClient httpClient, ILogger<HttpClientService> logger) |
|||
{ |
|||
_httpClient = httpClient; |
|||
_logger = logger; |
|||
|
|||
// 设置默认请求头
|
|||
_httpClient.DefaultRequestHeaders.Add("User-Agent", "LTEMvcApp/1.0"); |
|||
_httpClient.Timeout = TimeSpan.FromSeconds(30); |
|||
|
|||
_logger.LogInformation("HttpClientService 初始化完成"); |
|||
} |
|||
|
|||
#region GET请求方法
|
|||
|
|||
/// <summary>
|
|||
/// 发送GET请求
|
|||
/// </summary>
|
|||
/// <param name="url">请求URL</param>
|
|||
/// <param name="headers">自定义请求头</param>
|
|||
/// <returns>响应内容</returns>
|
|||
public async Task<string> GetAsync(string url, Dictionary<string, string>? headers = null) |
|||
{ |
|||
try |
|||
{ |
|||
_logger.LogInformation("发送GET请求到: {Url}", url); |
|||
|
|||
using var request = new HttpRequestMessage(HttpMethod.Get, url); |
|||
|
|||
if (headers != null) |
|||
{ |
|||
foreach (var header in headers) |
|||
{ |
|||
request.Headers.Add(header.Key, header.Value); |
|||
} |
|||
} |
|||
|
|||
var response = await _httpClient.SendAsync(request); |
|||
response.EnsureSuccessStatusCode(); |
|||
|
|||
var content = await response.Content.ReadAsStringAsync(); |
|||
_logger.LogInformation("GET请求成功,响应长度: {Length}", content.Length); |
|||
|
|||
return content; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
_logger.LogError(ex, "GET请求失败: {Url}", url); |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 发送GET请求并反序列化为指定类型
|
|||
/// </summary>
|
|||
/// <typeparam name="T">目标类型</typeparam>
|
|||
/// <param name="url">请求URL</param>
|
|||
/// <param name="headers">自定义请求头</param>
|
|||
/// <returns>反序列化的对象</returns>
|
|||
public async Task<T> GetAsync<T>(string url, Dictionary<string, string>? headers = null) |
|||
{ |
|||
var json = await GetAsync(url, headers); |
|||
return JsonConvert.DeserializeObject<T>(json) ?? throw new InvalidOperationException("反序列化失败"); |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region POST请求方法
|
|||
|
|||
/// <summary>
|
|||
/// 发送POST请求
|
|||
/// </summary>
|
|||
/// <param name="url">请求URL</param>
|
|||
/// <param name="content">请求内容</param>
|
|||
/// <param name="contentType">内容类型</param>
|
|||
/// <param name="headers">自定义请求头</param>
|
|||
/// <returns>响应内容</returns>
|
|||
public async Task<string> PostAsync(string url, string content, string contentType = "application/json", Dictionary<string, string>? headers = null) |
|||
{ |
|||
try |
|||
{ |
|||
_logger.LogInformation("发送POST请求到: {Url}", url); |
|||
|
|||
using var request = new HttpRequestMessage(HttpMethod.Post, url); |
|||
|
|||
if (headers != null) |
|||
{ |
|||
foreach (var header in headers) |
|||
{ |
|||
request.Headers.Add(header.Key, header.Value); |
|||
} |
|||
} |
|||
|
|||
request.Content = new StringContent(content, Encoding.UTF8, contentType); |
|||
|
|||
var response = await _httpClient.SendAsync(request); |
|||
response.EnsureSuccessStatusCode(); |
|||
|
|||
var responseContent = await response.Content.ReadAsStringAsync(); |
|||
_logger.LogInformation("POST请求成功,响应长度: {Length}", responseContent.Length); |
|||
|
|||
return responseContent; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
_logger.LogError(ex, "POST请求失败: {Url}", url); |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 发送POST请求(JSON格式)
|
|||
/// </summary>
|
|||
/// <param name="url">请求URL</param>
|
|||
/// <param name="data">要发送的数据对象</param>
|
|||
/// <param name="headers">自定义请求头</param>
|
|||
/// <returns>响应内容</returns>
|
|||
public async Task<string> PostJsonAsync(string url, object data, Dictionary<string, string>? headers = null) |
|||
{ |
|||
var json = JsonConvert.SerializeObject(data); |
|||
return await PostAsync(url, json, "application/json", headers); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 发送POST请求并反序列化响应
|
|||
/// </summary>
|
|||
/// <typeparam name="T">响应类型</typeparam>
|
|||
/// <param name="url">请求URL</param>
|
|||
/// <param name="data">要发送的数据对象</param>
|
|||
/// <param name="headers">自定义请求头</param>
|
|||
/// <returns>反序列化的响应对象</returns>
|
|||
public async Task<T> PostJsonAsync<T>(string url, object data, Dictionary<string, string>? headers = null) |
|||
{ |
|||
var json = await PostJsonAsync(url, data, headers); |
|||
return JsonConvert.DeserializeObject<T>(json) ?? throw new InvalidOperationException("反序列化失败"); |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region PUT请求方法
|
|||
|
|||
/// <summary>
|
|||
/// 发送PUT请求
|
|||
/// </summary>
|
|||
/// <param name="url">请求URL</param>
|
|||
/// <param name="content">请求内容</param>
|
|||
/// <param name="contentType">内容类型</param>
|
|||
/// <param name="headers">自定义请求头</param>
|
|||
/// <returns>响应内容</returns>
|
|||
public async Task<string> PutAsync(string url, string content, string contentType = "application/json", Dictionary<string, string>? headers = null) |
|||
{ |
|||
try |
|||
{ |
|||
_logger.LogInformation("发送PUT请求到: {Url}", url); |
|||
|
|||
using var request = new HttpRequestMessage(HttpMethod.Put, url); |
|||
|
|||
if (headers != null) |
|||
{ |
|||
foreach (var header in headers) |
|||
{ |
|||
request.Headers.Add(header.Key, header.Value); |
|||
} |
|||
} |
|||
|
|||
request.Content = new StringContent(content, Encoding.UTF8, contentType); |
|||
|
|||
var response = await _httpClient.SendAsync(request); |
|||
response.EnsureSuccessStatusCode(); |
|||
|
|||
var responseContent = await response.Content.ReadAsStringAsync(); |
|||
_logger.LogInformation("PUT请求成功,响应长度: {Length}", responseContent.Length); |
|||
|
|||
return responseContent; |
|||
} |
|||
catch (HttpRequestException ex) |
|||
{ |
|||
_logger.LogError(ex, "PUT请求失败: {Url}", url); |
|||
throw; |
|||
} |
|||
catch (TaskCanceledException ex) |
|||
{ |
|||
_logger.LogError(ex, "PUT请求超时: {Url}", url); |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 发送PUT请求(JSON格式)
|
|||
/// </summary>
|
|||
/// <param name="url">请求URL</param>
|
|||
/// <param name="data">要发送的数据对象</param>
|
|||
/// <param name="headers">自定义请求头</param>
|
|||
/// <returns>响应内容</returns>
|
|||
public async Task<string> PutJsonAsync(string url, object data, Dictionary<string, string>? headers = null) |
|||
{ |
|||
var json = JsonConvert.SerializeObject(data); |
|||
return await PutAsync(url, json, "application/json", headers); |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region DELETE请求方法
|
|||
|
|||
/// <summary>
|
|||
/// 发送DELETE请求
|
|||
/// </summary>
|
|||
/// <param name="url">请求URL</param>
|
|||
/// <param name="headers">自定义请求头</param>
|
|||
/// <returns>响应内容</returns>
|
|||
public async Task<string> DeleteAsync(string url, Dictionary<string, string>? headers = null) |
|||
{ |
|||
try |
|||
{ |
|||
_logger.LogInformation("发送DELETE请求到: {Url}", url); |
|||
|
|||
using var request = new HttpRequestMessage(HttpMethod.Delete, url); |
|||
|
|||
if (headers != null) |
|||
{ |
|||
foreach (var header in headers) |
|||
{ |
|||
request.Headers.Add(header.Key, header.Value); |
|||
} |
|||
} |
|||
|
|||
var response = await _httpClient.SendAsync(request); |
|||
response.EnsureSuccessStatusCode(); |
|||
|
|||
var content = await response.Content.ReadAsStringAsync(); |
|||
_logger.LogInformation("DELETE请求成功,响应长度: {Length}", content.Length); |
|||
|
|||
return content; |
|||
} |
|||
catch (HttpRequestException ex) |
|||
{ |
|||
_logger.LogError(ex, "DELETE请求失败: {Url}", url); |
|||
throw; |
|||
} |
|||
catch (TaskCanceledException ex) |
|||
{ |
|||
_logger.LogError(ex, "DELETE请求超时: {Url}", url); |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region 工具方法
|
|||
|
|||
/// <summary>
|
|||
/// 设置默认请求头
|
|||
/// </summary>
|
|||
/// <param name="name">头部名称</param>
|
|||
/// <param name="value">头部值</param>
|
|||
public void SetDefaultHeader(string name, string value) |
|||
{ |
|||
_httpClient.DefaultRequestHeaders.Remove(name); |
|||
_httpClient.DefaultRequestHeaders.Add(name, value); |
|||
_logger.LogInformation("设置默认请求头: {Name} = {Value}", name, value); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 设置超时时间
|
|||
/// </summary>
|
|||
/// <param name="timeout">超时时间</param>
|
|||
public void SetTimeout(TimeSpan timeout) |
|||
{ |
|||
_httpClient.Timeout = timeout; |
|||
_logger.LogInformation("设置超时时间: {Timeout}", timeout); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 获取当前HttpClient实例
|
|||
/// </summary>
|
|||
/// <returns>HttpClient实例</returns>
|
|||
public HttpClient GetHttpClient() |
|||
{ |
|||
return _httpClient; |
|||
} |
|||
|
|||
#endregion
|
|||
} |
|||
} |
Loading…
Reference in new issue