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>