Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

604
Vistas
¿Cómo crear un servidor TCP asíncrono de una mejor manera que esto?

Tengo una aplicación de servidor para aceptar conexiones TCP de un conjunto de aproximadamente 10000 clientes (de hecho, dispositivos de campo con interfaz GPRS).

La parte que acepta conexiones es como tal:

 public async System.Threading.Tasks.Task AcceptConnections() { _listenerProxy.StartListen(); var taskList = new List<System.Threading.Tasks.Task>(); var application = _configManager.Configuration.GetSection("application"); var maxTasks = int.Parse(application["MaxTasksPerListener"]); while (true) { if (taskList.Count > maxTasks) { _logger.Info($"Waiting for handling task to be completed {_listenerProxy.Port}."); await System.Threading.Tasks.Task.WhenAny(taskList.ToArray()).ConfigureAwait(false); taskList.RemoveAll(t => t.IsCompleted); // at least one task affected, but maybe more } _logger.Info($"Waiting for client to be accepted on port {_listenerProxy.Port}."); (var readStream, var writeStream, var sourceIP, var sourcePort) = await _listenerProxy.AcceptClient().ConfigureAwait(false); _logger.Info($"Client accepted on port {_listenerProxy.Port}: IP:{sourceIP}, Port:{sourcePort}"); var clientContext = new ClientContext<TSendMessage, TReceiveMessage> { SourceAddress = sourceIP, SourcePort = sourcePort, DataAdapter = DataAdapterFactory<TSendMessage, TReceiveMessage>.Create(readStream, writeStream) }; taskList.Add(HandleClient(clientContext)); } }

El método HandleClient se define como:

 public async System.Threading.Tasks.Task HandleClient(ClientContext<TSendMessage, TReceiveMessage> clientContext);

Quiero poder manejar hasta un número predefinido de solicitudes en paralelo (la función del controlador es HandleClient ). Los clientes se conectarán, enviarán una pequeña cantidad de datos y luego cerrarán la conexión. Dado que todo el proyecto es asíncrono, tuve la tentación de probar un enfoque asíncrono también para esa parte.

Estoy bastante seguro de que no se recomienda esta solución, pero no tengo idea de cómo podría hacerse de una mejor manera. Encontré un tema muy relacionado aquí: ¿Cómo ejecutar una tarea en un nuevo hilo e inmediatamente regresar a la persona que llama?

Stephen Cleary hizo un comentario allí:

Bueno, lo primero que recomendaría es probar un ejercicio más simple. En serio, un servidor TCP asíncrono es una de las aplicaciones más complejas que puede elegir.

Entonces, bueno, ¿cuál sería el enfoque "correcto" en este caso? Sé que mi enfoque "funciona", pero tengo un mal presentimiento, especialmente porque HandleClient es más o menos "dispara y olvida". La única razón por la que estoy interesado en la tarea resultante es "acelerar" el rendimiento (originalmente era un vacío asíncrono). De hecho, tengo exactamente la misma pregunta que el TO en el enlace. Sin embargo, todavía no soy consciente de cuál podría ser el mayor problema en dicho enfoque.

Agradecería sugerencias constructivas... Gracias.

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

En una palabra: Cernícalo. Descargue todas estas preocupaciones y obtenga muchas otras bonificaciones al mismo tiempo, como la gestión avanzada de la vida útil del búfer y un diseño orientado a la sincronización. La API clave aquí es UseConnectionHandler<T> , por ejemplo:

 public static IWebHostBuilder CreateHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args).UseKestrel(options => { // listen on port 1000, using YourHandlerHere for the handler options.ListenLocalhost(1000, o => o.UseConnectionHandler<YourHandlerHere>()); }).UseStartup<Startup>();

Puede ver un ejemplo trivial pero ejecutable aquí (je, si llama "trivial" a un servidor similar a redis en su mayoría funcional), o tengo otros ejemplos en repositorios privados de github que probablemente podría enviarle, incluida una muestra donde todos lo que debe hacer es implementar el analizador de cuadros (el código de la biblioteca se ocupa de todo lo demás y funciona tanto en TCP como en UDP).

En cuanto al "acelerador", suena como un semáforo asíncrono; SemaphoreSlim tiene WaitAsync .

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda