Implementación de Envío de Mensajes en Aplicaciones Web B/S con ASP.NET

Este artículo presenta una solución para el envío de mensajes en aplicaciones web B/S (Browser/Server), diseñada para navegadores sin soporte HTML5. Se proporciona un esquema básico que puede nceesitar ajustes para gestión de errores y requisitos específicos.

Clace ResultadoAsincronoPersonalizado.cs


/// <summary>
/// Representa un cliente asíncrono para solicitudes HTTP.
/// </summary>
public class ResultadoAsincronoPersonalizado : IAsyncResult
{
    #region Implementación de IAsyncResult      
    public object EstadoAsincrono
    {
        get
        {
            return null;
        }
    }
    public WaitHandle EsperaAsincrona
    {
        get
        {
            return null;
        }
    }
    public bool CompletadoSincronamente
    {
        get
        {
            return false;
        }
    }
    public bool EstaCompletado
    {
        get
        {
            return false;
        }
    }
    #endregion

    private bool _finalizado = false;
    private HttpContext _contexto;
    private AsyncCallback _callback;
    private object _datosAdicionales;
    
    public ResultadoAsincronoPersonalizado(HttpContext contexto, AsyncCallback callback, object datosAdicionales)
    {
        _contexto = contexto;
        _callback = callback;
        _datosAdicionales = datosAdicionales;
    }

    public string MensajeContenido { get; set; }
    
    public void Enviar(object datos)
    {
        _contexto.Response.Write(MensajeContenido);
        if (_callback != null)
        {
            _callback(this);
        }
        _finalizado = true;
    }
}

Modelo Solicitud.cs


/// <summary>
/// Define el modelo para solicitudes de mensajes.
/// </summary>
public class ModeloSolicitud
{
    public TipoSolicitud Tipo { get; set; }
    /// <summary>
    /// Contenido del mensaje.
    /// </summary>
    public string Contenido { get; set; }
}

public enum TipoSolicitud
{
    InicioSesion = 0,
    Personal = 1,
    Todos = 2
}

Clase GestorMensajes.cs


/// <summary>
/// Gestiona la distribución de mensajes a clientes conectados.
/// </summary>
public class GestorMensajes
{
    private List<ResultadoAsincronoPersonalizado> _clientesConectados = new List<ResultadoAsincronoPersonalizado>();
    private static readonly GestorMensajes _instanciaUnica = new GestorMensajes();
    
    private GestorMensajes() { }
    
    public static GestorMensajes ObtenerInstancia()
    {
        return _instanciaUnica;
    }
    
    /// <summary>
    /// Procesa y distribuye mensajes según el tipo de solicitud.
    /// </summary>
    /// <param name="solicitud">Modelo de solicitud entrante.</param>
    /// <param name="clienteAsincrono">Instancia del cliente asíncrono.</param>
    public void ProcesarMensaje(ModeloSolicitud solicitud, ResultadoAsincronoPersonalizado clienteAsincrono)
    {
        switch (solicitud.Tipo)
        {
            case TipoSolicitud.InicioSesion:
                _clientesConectados.Add(clienteAsincrono);
                break;
            case TipoSolicitud.Personal:
                // Lógica para mensajes personales (a implementar)
                break;
            case TipoSolicitud.Todos:
                clienteAsincrono.MensajeContenido = solicitud.Contenido;
                clienteAsincrono.Enviar(null);

                foreach (var cliente in _clientesConectados)
                {
                    cliente.MensajeContenido = solicitud.Contenido;
                    cliente.Enviar(null);
                }
                _clientesConectados.Clear();
                break;
        }
    }
}

Controlador EnvioMensajes.ashx


/// <summary>
/// Manejador HTTP para el envío de mensajes asíncrono.
/// </summary>
public class ControladorEnvioMensajes : IHttpAsyncHandler
{
    public IAsyncResult BeginProcessRequest(HttpContext contexto, AsyncCallback callback, object datosExtra)
    {
        var clienteAsincrono = new ResultadoAsincronoPersonalizado(contexto, callback, datosExtra);
        
        int tipoValor;
        int.TryParse(contexto.Request["tipo"], out tipoValor);
        TipoSolicitud tipoSolicitud;
        
        switch (tipoValor)
        {
            case 1: tipoSolicitud = TipoSolicitud.Personal; break;
            case 2: tipoSolicitud = TipoSolicitud.Todos; break;
            default: tipoSolicitud = TipoSolicitud.InicioSesion; break;
        }
        
        string contenidoMensaje = contexto.Request["contenido"];
        var solicitud = new ModeloSolicitud
        {
            Tipo = tipoSolicitud,
            Contenido = contenidoMensaje
        };
        
        GestorMensajes.ObtenerInstancia().ProcesarMensaje(solicitud, clienteAsincrono);
        return clienteAsincrono;
    }

    public void EndProcessRequest(IAsyncResult resultado)
    {
        // Lógica post-procesamiento (opcional)
    }

    public void ProcessRequest(HttpContext contexto)
    {
        // Método no utilizado en modo asíncrono
    }

    public bool IsReusable
    {
        get { return false; }
    }
}

Página Demo.aspx



<html>
<head>
    <meta charset="utf-8" />
    <script src="/scripts/jquery-1.7.2.min.js"></script>
    <title>Demostración Envío de Mensajes</title>
    <script type="text/javascript">
        $(document).ready(function () {
            $('#btnEnviar').click(function () {
                $.ajax({
                    url: "ControladorEnvioMensajes.ashx",
                    type: 'POST',
                    data: {
                        tipo: 2,
                        contenido: $('#campoTextoCliente').val()
                    }
                });
            });
            
            iniciarConexion();
            
            function iniciarConexion() {
                $.ajax({
                    url: 'ControladorEnvioMensajes.ashx',
                    data: { tipo: 0, contenido: "0" },
                    type: 'POST',
                    success: function (respuesta) {
                        $('#areaServidor').val(respuesta);
                        iniciarConexion();
                    }
                });
            }
        });
    </script>
</head>
<body>
    <div>
        <label for="areaServidor">Mensajes del servidor:</label>
        <div>
            <textarea id="areaServidor" rows="4" cols="50"></textarea>
        </div>
    </div>
    <div>
        <label for="campoTextoCliente">Enviar mensaje:</label>
        <div>
            <input type="text" id="campoTextoCliente" />
        </div>
        <div>
            <button id="btnEnviar">Enviar</button>
        </div>
    </div>
</body>
</html>

Etiquetas: ASP.NET C# JavaScript jQuery HTTP Handler

Publicado el 7-11 20:02