Add files via upload

This commit is contained in:
weiaiweiai
2025-09-21 16:38:23 +08:00
committed by GitHub
commit a60afec5a8
11 changed files with 847 additions and 0 deletions

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

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