mirror of
https://github.com/weiaiweiai/NezhaAgentHTTPBridge.git
synced 2026-05-13 21:49:09 +08:00
Add files via upload
This commit is contained in:
43
WebApplication4/Controllers/WeatherForecastController.cs
Normal file
43
WebApplication4/Controllers/WeatherForecastController.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using WebApplication4.Services;
|
||||
|
||||
namespace WebApplication4.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class WeatherForecastController : ControllerBase
|
||||
{
|
||||
|
||||
private readonly ILogger<WeatherForecastController> _logger;
|
||||
private readonly WebSocketMessageStore _wsStore;
|
||||
|
||||
public WeatherForecastController(
|
||||
ILogger<WeatherForecastController> logger,
|
||||
WebSocketMessageStore wsStore)
|
||||
{
|
||||
_logger = logger;
|
||||
_wsStore = wsStore;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> WebSocket <20><>Ϣ
|
||||
[HttpGet("lastws")]
|
||||
public IActionResult GetLastWebSocketMessage()
|
||||
{
|
||||
var (message, ts) = _wsStore.Get();
|
||||
if (message == null)
|
||||
{
|
||||
return NotFound(new
|
||||
{
|
||||
success = false,
|
||||
message = "<22><>δ<EFBFBD>յ<EFBFBD><D5B5>κ<EFBFBD> WebSocket <20><>Ϣ<EFBFBD><CFA2>"
|
||||
});
|
||||
}
|
||||
|
||||
return Ok(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
34
WebApplication4/Program.cs
Normal file
34
WebApplication4/Program.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using WebApplication4.Services;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
builder.Services.AddControllers();
|
||||
|
||||
// ȫ<><C8AB><EFBFBD>ſ<EFBFBD> CORS<52><53><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ս<EFBFBD><D5BD><EFBFBD>
|
||||
builder.Services.AddCors(options =>
|
||||
{
|
||||
options.AddPolicy("AllowAll", policy =>
|
||||
policy.AllowAnyOrigin()
|
||||
.AllowAnyHeader()
|
||||
.AllowAnyMethod());
|
||||
});
|
||||
|
||||
// WebSocket <20><><EFBFBD><EFBFBD>
|
||||
builder.Services.AddSingleton<WebSocketMessageStore>();
|
||||
builder.Services.AddHostedService<WebSocketClientBackgroundService>();
|
||||
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
// builder.Services.AddSwaggerGen(); // <20><><EFBFBD><EFBFBD><EFBFBD>ٴ<EFBFBD><D9B4><EFBFBD>
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// <20><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD> MapControllers ֮ǰ
|
||||
app.UseCors("AllowAll");
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>м<EFBFBD><D0BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>ɷ<EFBFBD><C9B7>ڴ˴<DAB4><CBB4><EFBFBD>
|
||||
// app.UseHttpsRedirection();
|
||||
|
||||
app.MapControllers();
|
||||
|
||||
app.Run();
|
||||
31
WebApplication4/Properties/launchSettings.json
Normal file
31
WebApplication4/Properties/launchSettings.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:28450",
|
||||
"sslPort": 0
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "weatherforecast",
|
||||
"applicationUrl": "http://localhost:5020",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "weatherforecast",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
109
WebApplication4/Services/WebSocketClientBackgroundService.cs
Normal file
109
WebApplication4/Services/WebSocketClientBackgroundService.cs
Normal file
@@ -0,0 +1,109 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net.WebSockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace WebApplication4.Services
|
||||
{
|
||||
public class WebSocketClientBackgroundService : BackgroundService
|
||||
{
|
||||
private readonly ILogger<WebSocketClientBackgroundService> _logger;
|
||||
private readonly WebSocketMessageStore _store;
|
||||
// Ŀ<><C4BF> WebSocket <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
|
||||
private readonly Uri _uri = new("ws://127.0.0.1:8008/api/v1/ws/server");
|
||||
|
||||
// <20>ɵ<EFBFBD><C9B5><EFBFBD><EFBFBD><EFBFBD>
|
||||
private readonly TimeSpan _reconnectDelay = TimeSpan.FromSeconds(5);
|
||||
private const int ReceiveBufferSize = 8 * 1024;
|
||||
|
||||
public WebSocketClientBackgroundService(
|
||||
ILogger<WebSocketClientBackgroundService> logger,
|
||||
WebSocketMessageStore store)
|
||||
{
|
||||
_logger = logger;
|
||||
_store = store;
|
||||
}
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
_logger.LogInformation("WebSocket <20><>̨<EFBFBD><CCA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, Ŀ<><C4BF>: {Url}", _uri);
|
||||
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
using var client = new ClientWebSocket();
|
||||
try
|
||||
{
|
||||
client.Options.KeepAliveInterval = TimeSpan.FromSeconds(30);
|
||||
_logger.LogInformation("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> WebSocket...");
|
||||
await client.ConnectAsync(_uri, stoppingToken);
|
||||
_logger.LogInformation("WebSocket <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: {State}", client.State);
|
||||
|
||||
await ReceiveLoopAsync(client, stoppingToken);
|
||||
}
|
||||
catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
_logger.LogInformation("ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD>ֹ WebSocket ѭ<><D1AD><EFBFBD><EFBFBD>");
|
||||
break;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "WebSocket <20><><EFBFBD>ӻ<EFBFBD><D3BB><EFBFBD><EFBFBD>շ<EFBFBD><D5B7><EFBFBD><EFBFBD>쳣<EFBFBD><ECB3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> {Delay}s <20><><EFBFBD><EFBFBD><EFBFBD>ԡ<EFBFBD>",
|
||||
_reconnectDelay.TotalSeconds);
|
||||
}
|
||||
|
||||
if (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
await Task.Delay(_reconnectDelay, stoppingToken);
|
||||
}
|
||||
catch (OperationCanceledException) { }
|
||||
}
|
||||
}
|
||||
|
||||
_logger.LogInformation("WebSocket <20><>̨<EFBFBD><CCA8><EFBFBD><EFBFBD><EFBFBD>ѽ<EFBFBD><D1BD><EFBFBD><EFBFBD><EFBFBD>");
|
||||
}
|
||||
|
||||
private async Task ReceiveLoopAsync(ClientWebSocket client, CancellationToken ct)
|
||||
{
|
||||
var buffer = new byte[ReceiveBufferSize];
|
||||
|
||||
while (!ct.IsCancellationRequested && client.State == WebSocketState.Open)
|
||||
{
|
||||
using var ms = new MemoryStream();
|
||||
WebSocketReceiveResult? result;
|
||||
|
||||
do
|
||||
{
|
||||
var segment = new ArraySegment<byte>(buffer);
|
||||
result = await client.ReceiveAsync(segment, ct);
|
||||
|
||||
if (result.MessageType == WebSocketMessageType.Close)
|
||||
{
|
||||
_logger.LogWarning("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD>: {Desc}", result.CloseStatusDescription);
|
||||
await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", ct);
|
||||
return;
|
||||
}
|
||||
|
||||
ms.Write(buffer, 0, result.Count);
|
||||
}
|
||||
while (!result.EndOfMessage);
|
||||
|
||||
if (result.MessageType == WebSocketMessageType.Text)
|
||||
{
|
||||
var text = Encoding.UTF8.GetString(ms.ToArray());
|
||||
_store.Set(text);
|
||||
_logger.LogDebug("<22>յ<EFBFBD><D5B5>ı<EFBFBD><C4B1><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: {Len}", text.Length);
|
||||
}
|
||||
else if (result.MessageType == WebSocketMessageType.Binary)
|
||||
{
|
||||
_logger.LogDebug("<22><><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: {Len}", ms.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
30
WebApplication4/Services/WebSocketMessageStore.cs
Normal file
30
WebApplication4/Services/WebSocketMessageStore.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace WebApplication4.Services
|
||||
{
|
||||
public class WebSocketMessageStore
|
||||
{
|
||||
private string? _lastMessage;
|
||||
private DateTime? _receivedAtUtc;
|
||||
private readonly object _lock = new();
|
||||
|
||||
public void Set(string message)
|
||||
{
|
||||
if (message == null) return;
|
||||
lock (_lock)
|
||||
{
|
||||
_lastMessage = message;
|
||||
_receivedAtUtc = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
|
||||
public (string? Message, DateTime? ReceivedAtUtc) Get()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return (_lastMessage, _receivedAtUtc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
13
WebApplication4/WeatherForecast.cs
Normal file
13
WebApplication4/WeatherForecast.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace WebApplication4
|
||||
{
|
||||
public class WeatherForecast
|
||||
{
|
||||
public DateOnly Date { get; set; }
|
||||
|
||||
public int TemperatureC { get; set; }
|
||||
|
||||
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
||||
|
||||
public string? Summary { get; set; }
|
||||
}
|
||||
}
|
||||
9
WebApplication4/WebApplication4.csproj
Normal file
9
WebApplication4/WebApplication4.csproj
Normal file
@@ -0,0 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
8
WebApplication4/appsettings.Development.json
Normal file
8
WebApplication4/appsettings.Development.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
9
WebApplication4/appsettings.json
Normal file
9
WebApplication4/appsettings.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
||||
Reference in New Issue
Block a user