C# Ошибка подключения к серверу WebSocket

Рейтинг: 0Ответов: 0Опубликовано: 12.06.2023

При большом количестве подключений к серверу я получаю ошибку на стороне клиента Unable to connect to the remote server Невозможно подключиться к удаленному серверу При запуске количество ошибок всегда разное от 0 до 100 и т.п. При этом проект с сервером при нагрузке в 1000 подключений потребляет на 10мб больше озу, у клиентского приложения нагрузка полностью отсутствует. Подскажите как можно стабилизировать работу с сокетами. Код сервера Program.cs

using Microsoft.AspNetCore.HttpOverrides;
using System.Text.Json.Serialization;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers().AddJsonOptions(options =>
{
    options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
});
var connectionString = builder.Configuration.GetConnectionString("Programs");
builder.Services.AddSqlite<ContextProgram>(connectionString);
var app = builder.Build();
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.UseHttpsRedirection();

var webSocketOptions = new WebSocketOptions
{
    KeepAliveInterval = TimeSpan.FromMinutes(15)
};
app.UseWebSockets(webSocketOptions);
app.UseAuthorization();
app.MapControllers();

app.Run();

Код контролера

 public class SocketController : Controller
    {
        [HttpGet("/ws")]
        public async Task Get()
        {
            if (HttpContext.WebSockets.IsWebSocketRequest)
            {
                using var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync();
                await Socket(webSocket);
            }
            else
            {
             //   HttpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
            }
        }
        private async Task Socket(WebSocket webSocket)
        {
            try
            {
                var buffer = new byte[1024 * 4];
                var receiveResult = await webSocket.ReceiveAsync(
                    new ArraySegment<byte>(buffer), CancellationToken.None);

                while (!receiveResult.CloseStatus.HasValue)
                {
                    await webSocket.SendAsync(
                        new ArraySegment<byte>(buffer, 0, receiveResult.Count),
                        receiveResult.MessageType,
                        receiveResult.EndOfMessage,
                        CancellationToken.None);

                    receiveResult = await webSocket.ReceiveAsync(
                        new ArraySegment<byte>(buffer), CancellationToken.None);
                    await Task.Delay(10);
                }
                await webSocket.CloseAsync(
                    receiveResult.CloseStatus.Value,
                    receiveResult.CloseStatusDescription,
                    CancellationToken.None);
            }
            catch (Exception ex) 
            {
                string message = ex.Message.ToString();
               // webSocket.Abort();
            }
        }
    }

Код для проверки нагрузки на сервер или же просто подключение в многопотоке к серверу

using System.Net.WebSockets;
using System.Text;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;


SemaphoreSlim _semaphore;
CancellationTokenSource _cancelToken;
CancellationTokenSource CancellationTokenSource = new();
Console.WriteLine("Start");

int thread = 1000;
_semaphore = new SemaphoreSlim(thread);
_cancelToken = new CancellationTokenSource();

var pool = new List<Task>(thread);

for (int i = 0; i < thread; i++)
{
    await _semaphore.WaitAsync().ConfigureAwait(false);
    int val = i;
    ClientWebSocket webSocketClient = new ClientWebSocket();
    CancellationToken cancellationToken = new();
    pool.Add(Task.Run(async () =>
    {
        await Socket(webSocketClient, cancellationToken, val);
        _semaphore.Release();
    }, _cancelToken.Token));
}

await Task.WhenAll(pool.ToArray()).ConfigureAwait(false);
Console.WriteLine("Done");
Console.ReadKey();
async Task Socket(ClientWebSocket webSocketClient, CancellationToken cancellationToken, int i)
{
    string error = "";
    try
    {
        await webSocketClient.ConnectAsync(new Uri("ws://localhost:5000/ws"), cancellationToken).ConfigureAwait(false);
        if (webSocketClient.State == WebSocketState.Open)
        {
            await Send(webSocketClient, i.ToString(), cancellationToken);
            await SocketNew(webSocketClient);
        }
    }
    catch (Exception ex)
    {
        error = ex.Message.ToString();
        Console.WriteLine("Ошибка подключения" + $" {error}");
        return;
    }
}
async Task Send(ClientWebSocket webSocketClient, string requestString, CancellationToken cancellationToken)
{
    var requestBytes = UTF8Encoding.UTF8.GetBytes(requestString);
    var subscribeRequest = new ArraySegment<byte>(requestBytes);
    await webSocketClient.SendAsync(subscribeRequest, WebSocketMessageType.Text, true, cancellationToken).ConfigureAwait(false);
}
async Task SocketNew(WebSocket webSocket)
{
    try
    {
        var buffer = new byte[1024 * 4];
        var receiveResult = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
        while (!receiveResult.CloseStatus.HasValue)
        {
            string message = Encoding.UTF8.GetString(buffer, 0, receiveResult.Count);
            Console.WriteLine("Ответ от сокета " + message + $" Поток: {Thread.CurrentThread.ManagedThreadId}");
            if (message != "")
            {
                await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Connection closed", CancellationToken.None);
                return;
            }
            receiveResult = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("Ошибка при получение ответа");
    }
}

Ошибка Ошибка подключения System.Net.WebSockets.WebSocketException (0x80004005): Unable to connect to the remote server ---> System.Net.Http.HttpRequestException: Подключение не установлено, т.к. конечный компьютер отверг запрос на подключение. (localhost:5001) ---> System.Net.Sockets.SocketException (10061): Подключение не установлено, т.к. конечный компьютер отверг запрос на подключение. at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketErr or error, CancellationToken cancellationToken) at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.S ources.IValueTaskSource.GetResult(Int16 token) at System.Net.Sockets.Socket.g__WaitForConnectWithCancellation|277_0( AwaitableSocketAsyncEventArgs saea, ValueTask connectTask, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.ConnectToTcpHostAsync(String host, Int32 port, HttpRequestMessage initialRequest, Boolean async, CancellationToken cancellationToken) --- End of inner exception stack trace --- at System.Net.Http.HttpConnectionPool.ConnectToTcpHostAsync(String host, Int32 port, HttpRequestMessage initialRequest, Boolean async, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessag e request, Boolean async, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.AddHttp11ConnectionAsync(HttpRequestMessage request) at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1.WaitWithCancellati onAsync(CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.GetHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpReq uestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken) at System.Net.Http.DiagnosticsHandler.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.WebSockets.WebSocketHandle.ConnectAsync(Uri uri, CancellationToken cancellationToken, ClientWebSocketOptions options) at System.Net.WebSockets.WebSocketHandle.ConnectAsync(Uri uri, CancellationToken cancellationToken, ClientWebSocketOptions options) at System.Net.WebSockets.ClientWebSocket.ConnectAsyncCore(Uri uri, CancellationToken cancellationToken) at Program.<>c__DisplayClass0_0.<<$>g__Socket|0>d.MoveNext() in D:\Project\Visul studio\Delete2\Delete2\Program.cs:line 43

Ответы

Ответов пока нет.