Noticias Weblogs Foros Wiki Código

Meta-Info

¿Que es?

Planeta Código es un agregador de weblogs sobre programación y desarrollo en castellano. Si eres lector te permite seguirlos de modo cómodo en esta misma página o mediante el fichero de subscripción.

rss subscripción

Sponsors

Puedes utilizar las siguientes imagenes para enlazar PlanetaCodigo:
planetacodigo

planetacodigo

Si tienes un weblog de programación y quieres ser añadido aquí, envíame un email solicitándolo.

Idea: Juanjo Navarro

Diseño: Albin

Archivos

Picando Código

¿Y si juntamos a la comunidad de usuarios ArchLinux del Uruguay?

Enero 26th, 2012

ArchLinux

ArchLinux

Lo que dice el título, ¿y si juntamos un grupo de usuarios ArchLinux en un mismo espacio física esporádicamente y nos unimos a trabajar con algun(os) objetivo(s) en común?

En un principio pensé que la mejor forma de convocar a los usuarios a unirse en grupo era crear una lista de correo, un blog, o algo así. Pero eso son solo herramientas, preferí empezar sin mucha ambición con este post (gracias al principio de KISS). Los invito a dejar un comentario si quieren sumarse a la iniciativa. Hay que ver si hay más interesados, y después entre los que seamos vemos qué se arma :)

Se me ocurren varias razones de por qué esto es una buena idea. Una buena parte de lo positivo de ir a una reunión de personas técnicas (hackatón, conferencias y demás) es conocer a otras personas con los mismo intereses. Ni que hablar que las charlas suelen ser bastante interesantes. Si nos entretenemos leyéndonos por foros, redes sociales y blogs, mejor la vamos a pasar conversando mientras tomamos alguna cerveza y comemos alguna pizza.

A continuación listo algunos objetivos/ideas/razones más que me vienen en la cabeza sin caer en nada muy ambicioso.

Si hay convocatoria, coordinamos una fecha y me comprometo a conseguir un lugar para reunirnos por primera vez y ver qué sale. No hay mucha idea o compromiso, simplemente juntarse a ver qué sale.

Para finalizar el post, los dejo con un texto de la wiki:

En Biología, mutualismo es una interacción entre dos organismos en que ambos organismos obtienen beneficio. Este principio puede también ser aplicado a miembros proactivos y motivados de la comunidad de ARCH que quieren estar involucrados y contribuir a su distribución favorita GNU/Linux. Esta participación beneficia no solo a los miembros de la comunidad y sus compañeros Arches, pero también a todos los fans potenciales de Software libre y de codigo abierto

» Leer más, comentarios, etc...

Koalite's blog

Diseño Web Sensible y Grids CSS

Enero 26th, 2012

Ya he dicho en alguna ocasión que me interesa bastante el tema de la experiencia de usuario, aunque luego la parte de diseño gráfico que suele llevar asociada no sea mi fuerte y acabe basándome más en la teoría que en el talento.

En el mundo del diseño web últimamente está muy de moda el Responsive Web Design, que podríamos traducir como diseño sensible o más bien como “diseño que responde bien”. Se trata de intentar diseñar las páginas web para que se adapten correctamente a distintas resoluciones y formatos de pantalla, y es algo que hoy en día cobra una importancia especial con la gran variedad de dispositivos que se usan para navegar por internet.

Para conseguir esto, siempre existe la opción de desarrollar distintas versiones del sitio web adaptadas a cada formato que queramos soportar, pero eso implica un trabajo adicional que no siempre merece la pena y además supone un problema cuando aparecen nuevos formatos que no teníamos previsto.

El responsive design aprovecha las características de CSS3 y media queries para aplicar distintos formatos en función de las características del dispositivo que está accediendo a la página.

Una forma muy extendida de implementar esto es estructurar la página a partir de un grid y maquetar la información ajustándola a ese grid:

Estructura de una página basada en un grid

Estructura de una página basada en un grid de 7 columnas

Una vez que tenemos la información estructurada, aplicando las técnicas CSS adecuadas es relativamente fácil conseguir adaptarlo al tamaño de pantalla del dispositivo:

Ejemplo de web adaptada a distintas resoluciones

Ejemplo de web adaptada a distintas resoluciones

En este ejemplo se ve como al reducir el ancho de la pantalla, el contenido se reformatea reduciendo el tamaño de las columnas del grid, llegando incluso a apilar las columnas para pasar a un formato completamente vertical apto para teléfonos móviles. Se puede comprobar fácilmente accediendo a la página y redimensionando la ventana del navegador.

Para ayudarnos a implementar esto, existen muchos frameworks CSS para responsive design que nos facilitan bastante la vida. Algunos están basados en grids fluidos, en los cuales la anchura de las columnas se ajusta automáticamente al tamaño de la pantalla, y otros en grids fijos, que mantienen constante la anchura de las columnas pero varían el número de columnas en función del tamaño de la pantalla. Entre los frameworks más conocidos están:

Personalmente me parece una idea bastante buena, pero hay puntos que no acaban de gustarme. Me parece que se sacrifica parte del contenido semántico del documento en favor de la maquetación, algo que ya ocurría hace unos cuantos años con el abuso de las tablas. Ahora parece que, mientras se usen divs en lugar de tablas, todo vale.

Por otra parte, casi todos estos sistemas utilizan clases CSS que no tiene valor semántico, sólo tienen valor para formatear la información. En un mundo ideal, las clases CSS que aparecen en el documento HTML no deberían definir el cómo (formato) sino el qué (intención), deberían ser algo declarativo.

Por ejemplo, si en una página queremos marcar el importe total de una compra, deberíamos marcarlo como y luego asignar en la hoja de estilo a la clase total-amount una fuente negrita, más grande o lo que queramos. Con este tipo de frameworks se fomenta más usar algo de la forma , penalizando la estructura semántica del documento. Es lo mismo que ocurre al utilizar otros frameworks de diseño web como jquery-ui o jquery-mobile.

Una excepción a esto es Semantic Grid System, que intenta no manchar el documento html con sus clases CSS. Para ello, aplica sus estilos mediante mixins con LESS, SCSS o Stylus.

En cualquier caso, las ventajas que aportan el uso de este tipo de frameworks son considerables, por lo que a veces resulta mejor ser más pragmático y aprovecharlos. A fin de cuentas, lo que realmente importa es aportar valor al usuario/negocio, y para ello estos frameworks pueden ser de mucha ayuda.




Compartir enlace:
Facebook Twitter Email

No hay posts relacionados.

» Leer más, comentarios, etc...

Arragonán

Don’t Censor Me!

Enero 26th, 2012

Don’t Censor Me!

Via Pablo Jimeno

» Leer más, comentarios, etc...

xailer.info (esp)

Error.log

Enero 25th, 2012

Cuando lanzamos una aplicación desde el IDE y aparece un error en tiempo de ejecución sucede que, por motivos que van desde el cansancio o la falta de concentración hasta directamente porque se ha producido un error no recuperable (recursión, GPF, etc.), se cierra la aplicación sin darnos tiempo a anotar en qué lugar del código estaba el error.


ErrorLogError

Para evitar tener que reproducir otra vez cada uno de los pasos para llegar al error usaremos este plugin que añade una nueva opción al menú Ver del IDE que permite mostrar la información de error completa o resumida así como borrar el archivo del disco cuando ya no es necesario.

ErrorLogMenu

Desde la vista error.log es posible copiar la información del error al portapapeles en el mismo formato en que se está mostrando, completa o resumida, para, por ejemplo, enviarla por correo:

ErrorLogView

El archivo para descargar: ErrorLog

El plugin sólo funciona con Xailer 2.5 y Xailer 2.5.1

» Leer más, comentarios, etc...

Picando Código

Disponible Oil Rush 1.00 :)

Enero 25th, 2012

Oil Rush

Oil Rush

El excelente juego de estrategia naval en tiempo real Oil Rush (clic en el enlace para leer mi reseña) está disponible en su versión 1.00. Aquellos que lo preordenamos lo podemos descargar ya desde Unigine Online Store.

Se está trabajando en versiones para Steam, Desura y Ubuntu Software. Éstas estarán disponibles en uno o dos días.

La versión 1.00 nos trae el tan esperado modo de campaña para un jugador. Pre ordené el juego en marzo del año pasado, y desde entonces he ido viendo cómo evoluciona poco a poco con cada nueva versión. Ahora me toca el turno de hacer la campaña y ver qué han estado preparando los desarrolladores para nosotros…

Es un juego bastante importante en lo que respecta al mundillo de videojuegos en plataformas GNU/Linux. Fue construido sobre el motor Unigine que da la oportunidad de realizar unos gráficos 3D impresionantes, corriendo de forma nativa en nuestro querido sistema.

Con suerte el juego tenga éxito, así lo espero. Esto abriría más el mercado de videojuegos en GNU/Linux, dándole la publicidad necesaria a su motor para que otras compañías lo tengan en cuenta a la hora de desarrollar sus juegos.

Ya estoy descargando esta nueva versión, y más tarde tendré la oportunidad de probarlo. Ahí les contaré qué me pareció. Mientras les dejo algunas fotos de versiones anteriores para que se hagan una idea de los excelentes gráficos del juego:

Oil Rush 0.66

Oil Rush 0.82

 

» Leer más, comentarios, etc...

Variable not found

Libro: Dependency injection in .NET

Enero 25th, 2012

La inyección de dependencias es uno de esos conceptos rodeados de misterio que parecen reservados a gurús, arquitectos, y otros profesionales de gama alta, y aplicables exclusivamente en proyectos mastodóndicos.



Y nada más lejos de la realidad: DI se basa en principios relativamente simples, e incluso diría intuitivos, para lograr evitar el acoplamiento entre componentes, es aplicable en todo tipo y tamaño de aplicaciones, y por tanto todas ellas pueden beneficiarse de las ventajas que aporta, como la simplicidad, mantenibilidad, extensibilidad, o facilidad para la realización de pruebas unitarias.



Dependency Injection in .NET. Manning.Pero, sinceramente, jamás pensé que el tema que pudiera dar tanto de sí como para escribir un libro. Por eso me ha sorprendido la lectura, por cortesía de Auges, del libro “Dependency Injection in .NET”, escrito por por Mark Seemann y publicado por la editorial Manning, donde he podido comprobar que mis conocimientos sobre inyección de dependencias, aunque válidos, eran bastante superficiales.



El libro se estructura en cuatro grandes bloques a través de los cuales se realiza un completo recorrido guiado por los conceptos, utilización y herramientas para aplicar DI:

En definitiva, se trata una lectura recomendable para desarrolladores .NET, tanto para aquellos que no hayan tenido experiencia previa con la Inyección de Dependencias y anden buscando fórmulas para reducir el acoplamiento entre componentes, como para los que ya se han enfrentado a ella y desean conocer en mayor profundidad las bases que la sustentan.

Como puntos negativos, que está disponible exclusivamente en inglés, y que algunos capítulos se hacen algo densos y requieren varias pasadas para poder asimilar las ideas transmitidas.



Enlace: http://www.manning.com/seemann/



Publicado en: Variable not found.



» Leer más, comentarios, etc...

Arragonán

Taller Spring I/O 2012: Modulariza tus aplicaciones Grails

Enero 25th, 2012

Este año volveré a estar por el Spring I/O (16 y 17 de Febrero 2012 en Madrid), en esta ocasión dirigiendo el taller Modulariza tus aplicaciones Grails :

Gracias a los plugins de grails liberados a la comunidad, podemos aprovechar el esfuerzo hecho por otros desarrolladores y reutilizar el trabajo que han hecho. El sistema de plugins de grails da múltiples puntos de extensión para la plataforma: permite añadir comandos nuevos a la CLI, servicios, clases de dominio, extender dinámicamente algunos comportamientos… En el taller sacaremos partido del sistema de plugins de grails para reutilizar trabajo entre distintas de nuestras aplicaciones, veremos algunos ejemplos y desarrollaremos un plugin a modo de ejemplo.

Básicamente, mostraremos de forma práctica como reutilizar código en nuestros proyectos del día a día, más allá de liberar plugins que sólo tengan sentido ser liberados para el resto de la comunidad.

Este año volverán a ser 2 días de charlas y talleres, un eventazo a un precio de risa. Como podéis ver en la agenda, hay buena cantidad y calidad de ponentes, incluida alguna rockstar internacional entre ellos.

Cualquiera que trabaje o le interesen tecnologías alrededor de los ecosistemas Spring, Grails o Groovy debería asistir a este evento; o también a quienes les interesan cosas relacionadas con Mongodb, Scala, ElasticSearch, RabbitMQ o incluso temas de cloud computing.

Pero seguro que lo mejor está por los pasillos, durante los cafés y las comidas… o, por descontado, en la fiestaca del jueves :) .

Nos vemos en el Spring I/O!

» Leer más, comentarios, etc...

Variable not found

SignalR (II): Conexiones persistentes

Enero 24th, 2012

Hace poco estuvimos viendo por aquí conceptos básicos sobre SignalR, el componente que nos permite crear espectaculares aplicaciones en las que múltiples usuarios pueden estar colaborando de forma simultánea, asíncrona, y en tiempo real.



Entre otras cosas, comentábamos que SignalR  crea una capa de abstracciones sobre una conexión virtual permanente entre cliente y servidor, sobre la que podemos trabajar de diferentes formas:

En este post estudiaremos la primera opción, conexiones persistentes. Los hubs los veremos en un artículo posterior de la serie, aunque si sois impacientes ya podéis ir leyendo el fantástico post del amigo Marc Rubiño sobre el tema, “Push con SignalR”.



Demo de conexiones persistentesBueno, pues vamos al tema: emplearemos esta vía para implementar una funcionalidad bastante simple, pero nada trivial utilizando las herramientas habituales de ASP.NET: mostrar en una página, en tiempo real, información sobre los usuarios que están llegando a ella, los que la abandonan y el número de usuarios que hay conectados justo en ese momento, en tiempo real.



Para ello haremos lo siguiente:

  1. En el lado servidor, implementaremos un servicio (endpoint) SignalR, que es el que procesará las conexiones y desconexiones de clientes, y enviará información actualizada por las conexiones abiertas.
  2. Registraremos este endpoint durante la inicialización de la aplicación, asociándole una URL de acceso a las funcionalidades del servicio.
  3. En el lado cliente implementaremos la conexión con el servicio, capturaremos la información que nos vaya enviando y la mostraremos en la página en forma de log.
El resultado lucirá tal y como se muestra en la captura de pantalla adjunta. Aunque si lo preferís, podéis verlo en vivo y en directo descargando y ejecutando el proyecto de demostración que encontraréis al final de este artículo.



Ya en el post anterior de la serie vimos cómo descargar e instalar SignalR en un proyecto, así que vamos a suponer que ese paso ya lo hemos realizado previamente.

1. Implementación del endpoint

El endpoint, o servicio SignalR, que vamos a implementar utilizando el enfoque de conexión persistente es simplemente una clase que hereda de SignalR.PersistentConnection, en la que podemos sobrescribir los métodos que necesitemos para implementar nuestras funcionalidades. En ella encontramos métodos como OnConnected(), OnDisconnect(), OnReceived(), y bastantes más, que nos permiten tomar el control cuando se producen determinados eventos de interés en la conexión:

    public class VisitorsService : PersistentConnection
    {
        protected override void  OnConnected(HttpContextBase context, string clientId) { ... }
        protected override void  OnDisconnect(string clientId) { ... }
        protected override void  OnReceived(string clientId, string data) { ... }
        // [...]
    }
Observad que el interfaz es bastante similar a la que encontramos al trabajar directamente con sockets: podemos introducir lógica cuando un nuevo cliente se conecte sobrescribiendo el método OnConnected(),  cuando se desconecte, haciendo lo propio con OnDisconnect(), o cuando el cliente envíe algún tipo de mensaje al servidor, que ejecutará la funcionalidad implementada en OnReceived().



De la misma forma, la clase base PersistentConnection ofrece mecanismos para enviar mensajes directos a un cliente, a grupos de ellos, o a todos los clientes conectados.



Volviendo al sistema que estamos desarrollando, básicamente para alcanzar nuestros objetivos necesitamos:

1.1. Notificando a los clientes las nuevas conexiones

Cuando se realiza una nueva conexión al servicio, es decir, la llegada de un nuevo cliente, SignalR invocará al método OnConnected() del endpoint suministrándole el contexto de la petición HTTP actual, y un “ClientId”. El primero nos puede ser muy interesante para acceder a información de la petición (como el navegador, IP, cookies, información de autenticación, etc.), y el segundo es un identificador único generado por SignalR para realizar el seguimiento de la conexión.



Implementamos nuestro método y lo comentamos justo a continuación:

    protected override void OnConnected(HttpContextBase context, string clientId)
    {
        var clientDescription = getClientDescription(context);
        _clients.TryAdd(clientId, clientDescription);
 
        string text = clientDescription + " arrived.";
        var msg = new NotificationMessage(text, _clients.Count);
        Connection.Broadcast(msg);
    }
Lo primero que hacemos en la implementación del método es obtener una descripción textual del cliente (que puede ser el nombre del usuario autenticado, o su IP), utilizando el método getClientDescription(), que veremos más adelante. Esta descripción, asociada al ClientId, es almacenada en el diccionario estático _clients, lo que nos permitirá conocer en todo momento los clientes conectados.



Justo después componemos el mensaje y realizamos el envío a todos los usuarios conectados invocando el método Broadcast() de la propiedad de instancia Connection, que nos da acceso al canal virtual abierto entre clientes y servidor. El parámetro que recibe este método es de tipo object, y viajará serializado en formato JSON hasta cada uno de los clientes conectados; en este caso, hemos creado una clase llamada NotificationMessage que contiene toda la información que necesitamos suministrarles:

public class NotificationMessage
{
    public NotificationMessage(string message, int onlineUsers)
    {
        OnlineUsers = onlineUsers;
        Message = message;
    }
 
    public string Date
    {
        get { return System.DateTime.Now.ToLongTimeString(); }
    }
    public string Message { get; set; }
    public int OnlineUsers { get; set; }
}
Es conveniente tener en cuenta, sin embargo, que es posible enviar cualquier tipo de objeto: tipos propios (como en el ejemplo anterior), objetos anónimos, primitivos, o lo que se nos ocurra. Simplemente será serializado como JSON y llegará al cliente de forma directa (más adelante veremos cómo).



Los miembros auxiliares utilizados en el código anterior son los siguientes:

    private static ConcurrentDictionary<string, string> _clients =
        new ConcurrentDictionary<string, string>();
 
    private static string getClientDescription(HttpContextBase context)
    {
        var browser = context.Request.Browser.Browser + " " +
                        context.Request.Browser.Version;
        var name = context.Request.IsAuthenticated ?
                    "User " + context.User.Identity.Name :
                    "IP " + context.Request.UserHostAddress;
        return name + " (" + browser + ")";
    }
Observad que el diccionario donde almacenamos la información sobre las conexiones ha sido definido como ConcurrentDictionary para evitar problemas de concurrencia durante las actualizaciones, y es estático para que su información sea compartida entre todas las instancias del servicio.

1.2. Notificando a los clientes las desconexiones

Cuando SignalR detecta que un cliente se ha desconectado, invocará al método virtual OnDisconnect() del endpoint, lo cual nos permite introducir lógica de gestión del evento. En nuestro caso, simplemente necesitamos eliminar al cliente del diccionario donde los estamos almacenando,



De la misma forma, debemos controlar las desconexiones para notificar este hecho a los clientes aún conectados, para lo que sobrescribimos el método OnDisconnect():

    protected override void OnDisconnect(string clientId)
    {
        string text, clientDescription;
 
        if (_clients.TryRemove(clientId, out clientDescription))
            text = clientDescription + " is leaving.";
        else
            text = "Unknown user leaving.";
 
        var msg = new NotificationMessage(text, _clients.Count);
        Connection.Broadcast(msg);
    }
En este método recibimos el ClientId que SignalR asignó al cliente en el momento de iniciar la conexión; lo único que hacemos es buscarlo en el diccionario de clientes donde los estamos almacenando, eliminarlo, y enviar un mensaje broadcast al resto de usuarios indicando la desconexión que se ha producido.



Cuando implementéis funcionalidades en la desconexión, tened en cuenta que SignalR tarda unos segundos en darse cuenta de las desconexiones (recordad que con el transporte utilizado por defecto se trata de una conexión persistente virtual) por lo que puede aparecer un leve retraso en las notificaciones. Estos tiempos, en cualquier caso, pueden ser configurados (en el proyecto de demostración podéis ver cómo hacerlo).



[Actualización]: como bien indica Arturo en un comentario del post, para que las desconexiones sean notificadas correctamente es necesario utilizar IIS o IIS Express. Con Cassini (el servidor web integrado en VS) no funcionará bien este mecanismo.

1.3. Algunas observaciones adicionales

Al principio de comenzar a jugar con conexiones persistentes de SignalR, una de las cosas que pueden llamar la atención es que si en la implementación del método OnConnected() enviamos un broadcast a todos los usuarios conectados,  el usuario actual (el que ha provocado la llamada a OnConnected) no recibirá el mensaje; o en otras palabras, el broadcast llegará a todos los clientes excepto al que acaba de realizar la conexión.



Desconozco si se trata de un comportamiento por diseño, si es algo que se modificará en posteriores revisiones de SignalR (recordemos que en estos momentos es todavía una versión preliminar), o si simplemente se trata de un nombre para el método poco afortunado, pues en mi opinión da a entender que la conexión ya ha sido realizada y, por tanto, el broadcast debería llegarle también.



Pero en cualquier caso, en la implementación del proyecto de pruebas que podéis descargar al final de este post veréis cómo lo he solucionado incluyendo una llamada explícita (“ping”) desde el cliente al servidor para forzar el envío de un mensaje de actualización justo después de completarse la conexión. Conceptualmente, lo que se hace es:

Más adelante, cuando tratemos la parte cliente del servicio, veremos cómo está implementado el envío desde el cliente de este “ping”.

2. Registro de ruta

Una vez tenemos el servicio implementado, debemos registrar en el sistema de routing de ASP.NET una URL a través de la cual será posible acceder al mismo. El lugar idóneo para hacerlo, como siempre que se trata de cargar la tabla de rutas, es en el global.asax, para que se ejecute durante la inicialización de la aplicación.



Por ejemplo, en una aplicación ASP.NET MVC podría ser algo así:

    public static void RegisterSignalrConnections(RouteCollection routes)
    {
        routes.MapConnection<VisitorsService>("Visitors", "VisitorsService/{*operation}");
    }
 
    protected void Application_Start()
    {
        RegisterSignalrConnections(RouteTable.Routes);
        [...]
    }
Observad que lo único que estamos haciendo es añadir a la tabla de rutas una entrada en la que asociamos el servicio, en este caso nuestra clase VisitorsService, a la dirección “VisitorsService/{*operation}”, que será la URL de acceso al mismo.



El primer parámetro que enviamos al método MapConnection() es simplemente el nombre de la entrada en la tabla de rutas, no tiene demasiada importancia.

3. Implementación del cliente web

La implementación de clientes web para las conexiones persistentes desarrolladas con SignalR es bastante simple, y comienza incluyendo en la página o vista una referencia hacia la biblioteca cliente de este componente:

<script src="@Url.Content("~/Scripts/jquery.signalR.js")" type="text/javascript"></script>
Como siempre, esta inclusión puede realizarse a nivel de página, o bien en la Master o Layout si queremos aplicarlo a todas las vistas del sistema.

Nota: si queremos dar soporte a clientes antiguos que no soportan deserialización JSON de forma nativa (por ejemplo, IE7), será necesario descargar desde Nuget la biblioteca de scripts json2.js y referenciarla en la página antes de la carga de SignalR.js. En caso contrario, se lanzará una excepción con el error:



“SignalR: No JSON parser found. Please ensure json2.js is referenced before the SignalR.js file if you need to support clients without native JSON parsing support, e.g. IE<8” 
Centrándonos en nuestra aplicación, el marcado HTML será tan simple como el que se muestra a continuación, lo único que hacemos es dejar un “hueco” en el que introduciremos los mensajes que se vayan recibiendo del servidor:

<h2>Log</h2>
<div id="log"></div>
A continuación, necesitamos implementar el código de script que realice las siguientes tareas:

Y el código de script tampoco puede ser más sencillo:

<script type="text/javascript">
    $(function () {
        var conn = $.connection("VisitorsService");
        conn.received(function (data) {
            var text = data.Date + " - " + data.Message + " " +
                data.OnlineUsers + " users online.";
            
            $('#log').prepend("<div>" + text + "</div>");
        });
 
        conn.start(function () {
            conn.send("ping");
        });
    });
</script>
Lo comentamos muy rápidamente:

Y ¡esto es todo!



Si tenéis un ratillo, no dejéis de descargar el proyecto de prueba y jugar un rato con él. Y sobre todo, observad las pocas líneas de código que hemos tenido que emplear para resolver esta funcionalidad y comparadlo con lo que supondría implementarla de forma artesana, con las técnicas tradicionales.

Descargar proyecto de prueba.



En el próximo post de la serie veremos cómo utilizar los Hubs de SignalR, un planteamiento con una abstracción aún mayor sobre la conexión y una integración entre cliente y servidor simplemente espectacular.



Publicado en Variable not found.



» Leer más, comentarios, etc...

Najaraba.com: Software libre, metodologías ágiles y más.

Nueva etapa profesional: la inspiración

Enero 23rd, 2012

No sería capaz de reflejar mejor estos últimos cinco años trabajando en Biko de cómo ya los ha reflejado Jessi en su blog. Va de personas que son felices en su trabajo. Porque el desarrollo de software no es trabajar con ordenadores y picar código. El desarrollo de software es mucho más: son personas haciendo cosas grandes que disfrutan con lo que hacen, y sobre todo, con quien lo hacen. Este

» Leer más, comentarios, etc...

Koalite's blog

Demasiada abstracción

Enero 23rd, 2012

Hay veces que llegamos a un punto en que intentamos abstraer demasiado las cosas y acabamos teniendo lo que se suele llamar una leaky abstraction. Se trata de casos en los cuales el mecanismo de abstracción no es efectivo, aquello que queremos abstraer acaba traspasando la capa de abstración y lo único que conseguimos es una complicación innecesaria.

Recientemente he padecido un caso claro de esto usando la API de consultas QueryOver de NHibernate. QueryOver está diseñado como una implementación del patrón Query Object aprovechando expresiones lambda para hacer static reflection y conseguir así que el API sea type-safe y refactor friendly.

QueryOver intenta abstraer el acceso a la base datos, pero a la vez trata de mantener toda la potencia del SQL, por lo que en cuanto las consultas se complicando un poco acaba siendo un lío y la ganancia que tenemos por ser type-safe y refactor friendly no compensa la pérdida de legibilidad.

Veamos un ejemplo concreto bastante simpe. Supongamos que tenemos el típico modelo de clientes y pedidos y queremos lanzar una consulta para obtener el número de pedidos y el importe total pedido por cada cliente. La implementación con QueryOver es algo así:

Customer customer = null;
var stats = s.QueryOver()
    .JoinAlias(x => x.Customer, () => customer)
    .SelectList(lst => lst
                            .SelectGroup(() => customer.Id)
                            .SelectGroup(() => customer.Name)
                            .SelectSum(x => x.Total)
                            .SelectCount(x => x.Id))
    .List();

El resultado es bastante feo. Para poder hacer el equivalente al inner join de forma type-safe, tenemos que declarar una variable de tipo Customer que usamos únicamente como alias para usarla luego en las expresiones lambda. Además, para construir la lista de columnas a devolver se usa un builder (lst) que simplifica un poco las cosas pero no acaba de resultar claro.

Si la misma consulta la lanzamos con el equivalente HQL, el lenguaje de consultas de NHibernate, tenemos:

var stats = s.CreateQuery(@"select c.Id, c.Name, sum(o.Total), count(o.Id)
                            from Order o right join o.Customer c
                            group by c.Id, c.Name")
             .List();

Para cualquiera que esté acostumbrado a manejar SQL, está claro que la consulta resulta mucho más legible. Es cierto que no es type-safe no refactor friendly, pero en mi opinión la legibilidad lo compensa.

Parece que nuestra tendencia natural como desarrolladores es siempre abstraerlo todo, pero a veces hay que tener cuidado porque puede que estemos causando más problemas de los que solucionamos.




Compartir enlace:
Facebook Twitter Email

No hay posts relacionados.

» Leer más, comentarios, etc...

Escuela De Codigo

GitHub, para el que empieza con Git

Enero 23rd, 2012

La semana pasada vimos una corta y puntual introducción a Git, solo lo necesario para el que no sabe nada de control de versiones deje de vivir en la era del oscurantismo y pase a ser parte del cada dia mas grande, grupo de iluminados que hacen de su vida de desarrollador mas facil, utilizando Git. Pues bien hoy en dia no se puede mencionar Git sin decir GitHub. ¿Que es? ¿Como se sirve? ¿Con que lo aderezo? En este articulo conoceremos GitHub y lo mucho que nos puede ayudar.

¿Que es GitHub?

GitHub es un sitio web para alojar proyectos utilizando el sistema de control de versiones Git.

¿Necesitas alojar tu proyecto en algun repositorio Git que no sea en tu computadora? ¿No quieres perder tu tiempo configurando un servidor remoto como repositorio de Git? Entonces GitHub es para ti, un sitio web donde todos tus proyectos que utilicen Git estaran bien resguardados.

Seria muy injusto decir que GitHub solo es un simple sitio web para guardar repositorios Git. Porque la verdad es que es mucho mas que eso,es una “red social” donde los desarrolladores compartimos nuestro codigo fuente con otros. Todos los repositorios en GitHub son open source (todos los que no son de pago) asi que podemos descargarlos, clonarlos,enviar parches, corregir el codigo de otro, que otros nos envien sus cambios, etc, etc.

De esa forma no solo compartimos nuestro código, sino que lo exponemos a una audiencia de profesionales (como nosotros) para que lo puedan evaluar, corregir y mejorar :)

Para empezar, registrate en GitHub

Ingresa a https://github.com/plans , elige el plan gratuito, llena el formulario (bastante simple no tendras problemas) y ya estas registrado!

Mi primer repositorio

Vamos a estrenarnos dentro de GitHub, para eso ya debemos tener correctamente configurado Git, ¿No lo has hecho?? Tomate unos minutos para leer este articulo antes de continuar

Crea un nuevo repositorio

GitHub es tan bueno con nosotros, que inmediatamente despues de crear el repositorio nos indica como debemos proceder, asi que hagamos lo que dice

Sube el código

Antes que nada, crea en tu computadora la carpeta donde tendras el código fuente, abre una terminal y escribe

 mkdir Hola-Gato

y muevete dentro de la carpeta recien creada

 cd Hola-Gato

inicializa el repositorio Git

 git init

Los repositorios en GitHub tienen un archivo muy importante, el README, dentro de este archivo se colocan instrucciones que quieres que los desarrolladores lean desde que entran a ver tu repositorio, asi que no olvidemos crearlo. Utiliza Markdown para escribir en el.

touch README

Ahora que ya tienes un archivo en tu repositorio, lo agregamos

git add README

y ejecutamos nuestro primer commit

git commit -m “Primer commit en el proyecto”

Hasta este momento todo lo que hemos hecho, seria como cualquier proyecto en el que usemos Git, todo local, para relacionar nuestro código fuente con el repositorio remoto que recien hemos creado en GitHub debemos ejecutar lo siguiente

git remote add origin git@github.com:escueladecodigo/Hola-Gato.git

y finalmente subimos el codigo a GitHub

git push -u origin master

Ahora cuando demos en el enlace Continue veremos algo como lo siguiente

Ahora ya tienes tu primer repositorio en GitHub, listo para que cualquiera lo vea, lo clone, haga forks, te envié mejoras, etc, etc. Solo llénalo un poco con tu código, no creo que un repositorio con un solo archivo README sea muy llamativo para otros desarrolladores ;)

GitHub cuenta con tantas funcionalidades; resaltado de sintaxis, seguir desarrolladores, clonar repositorios, etc, etc. Por el momento dejare que tu curiosidad trabaje un poco y explores todo lo que Git junto con GitHub puede ofrecerte. En artículos posteriores iremos desglosando cada una de esas opciones, conociéndolas bien y sacandoles el máximo provecho posible. Así que no te pierdas los próximos artículos, te ayudaran no solo a conocer Git sino a usarlo como un ninja!

» Leer más, comentarios, etc...

xperiments.es

(English) i5hare project launched.

Enero 22nd, 2012

Disculpa, pero esta entrada está disponible sólo en English.

» Leer más, comentarios, etc...

xperiments.es

(English) StageWebViewBridge Update

Enero 22nd, 2012

Disculpa, pero esta entrada está disponible sólo en English.

» Leer más, comentarios, etc...

El blog de pico.dev

Errores de precisión, redondeo y representación con float y double

Enero 21st, 2012

Java
Los tipos de datos float y double aunque muy usados y útiles tienen defectos, como que no son capaces de representar el resultado de ciertas operaciones ariméticas entre números reales con total precisión, en algunos casos solo son capaces de representar aproximaciones a ellos y que las operaciones las realizan en base dos. Al igual que nosotros no podemos repsentar 1/3 con números en base diez con total exactitud (solo una aproximación 0,333333333... con treses hasta el infinito) a las computadoras les pasa otro tanto de lo mismo, aunque estas guardan los números en base dos. Por tanto usarlos para hacer ciertas operaciones aritméticas, y siendo acumuladas varias de ellas, puede dar lugar a errores de redondeo y precisión en el resultado final. Por estos motivos usar estos tipos de datos no son los más adecuados para trabajar en una aplicación que calcule precios. Veámoslo con un ejemplo.



Supongamos que tenemos una cantidad de dinero tal que 100,05 a la que aplicamos un 10% de descuento y posteriormente un 5% en concepto de impuestos. Las líneas de código que calculan esto son:



import java.text.NumberFormat;



double amount = 100.05;

double discount = amount * 0.10;

double total = amount - discount;

double tax = total * 0.05;

double taxedTotal = tax + total;



NumberFormat money = NumberFormat.getCurrencyInstance();

System.out.println("Subtotal: "+ money.format(amount));

System.out.println("Discount: " + money.format(discount));

System.out.println("Total: " + money.format(total));

System.out.println("Tax: " + money.format(tax));

System.out.println("Tax+Total: " + money.format(taxedTotal));


Y el resultado es:



Subtotal: 100,05 €

Discount: 10,00 €

Total: 90,04 €

Tax: 4,50 €

Tax+Total: 94,55 €



Si nos fijamos en la suma de total más impuestos hay una diferencia de 0.01 y si presentamos un desglose de precios como este a un usuario puede que este piense que hay algún error en el cálculo, le genere desconfianza y no haga la compra en el peor de los casos. Viendo los valores sin los redondeos que hace NumberFormat tenemos:



Subtotal: 100.05

Discount: 10.005

Total: 90.045

Tax: 4.50225

Tax+Total: 94.54725



Los redondeos que hace NumberFormat es HALF_EVEN por defecto, de modo que cuando un decimal está equidistante a las dos partes se redondea a la parte par por lo que con una precisión de dos decimales:



Discount: 10.005 se redondea a 10.00

Total: 90.045 se redondea a 90.04

Tax: 4.50225  se redondea a 4.50

Tax+Total: 94.54725 se redondea a 94.55



En este caso se trata de un problema de redondeo pero ahora supongamos que tenemos una cantidad de 0,70 céntimos a la que no aplicamos un descuento pero si el procentaje de impuestos del 5%. Tendríamos:



import java.text.NumberFormat;

double amount = 0.70;

double tax = amount * 0.05;

double taxedTotal = tax + amount;



NumberFormat money = NumberFormat.getCurrencyInstance();

System.out.println("Subtotal: "+ money.format(amount));

System.out.println("Tax: " + money.format(tax));

System.out.println("Tax+Total: " + money.format(taxedTotal));


Subtotal: 0,70 €

Tax: 0,03 €

Tax+Total: 0,74 €



Nos encontramos otra vez con la diferencia de 0.01. Vemos los valores sin redondear por NumberFormat:



Subtotal: 0.7

Tax: 0.034999999999999996

Tax+Total: 0.735



Aquí se ve que el resultado de ciertas operaciones aritméticas entre datos double (o float) son almacenadas por una computadora con errores de precisión, 0.70 * 0.05 (debería ser 0.035).



Para evitar estos errores debemos utilizar la clase BigDecimal que pemite almacenar números con una precisión en la práctica infinita en base 10, realizar los cálculos como los humanos esperan, en base diez, y hacer los redondeos de precisión. Aplicando una precisión de dos decimales a los números y usando BigDecimal tenemos:



import java.math.BigDecimal;

import java.math.RoundingMode;

import java.text.NumberFormat;



RoundingMode RM = RoundingMode.HALF_EVEN;

BigDecimal amount = new BigDecimal("100.05");

BigDecimal discountPercent = new BigDecimal("0.10");

BigDecimal discount = amount.multiply(discountPercent).setScale(2, RM);

BigDecimal total = amount.subtract(discount).setScale(2, RM);

BigDecimal taxPercent = new BigDecimal("0.05");

BigDecimal tax = total.multiply(taxPercent).setScale(2, RM);

BigDecimal taxedTotal = total.add(tax).setScale(2, RM);

NumberFormat money = NumberFormat.getCurrencyInstance();

System.out.println("Subtotal : " + money.format(amount));

System.out.println("Discount : " + money.format(discount));

System.out.println("Total : " + money.format(total));

System.out.println("Tax : " + money.format(tax));

System.out.println("Tax+Total: " + money.format(taxedTotal));


Ahora los precios si están correctos:



Subtotal : 100,05 €

Discount : 10,00 €

Total : 90,05 €

Tax : 4,50 €

Tax+Total: 94,55 €



Para el otro caso en el que teníamos un error de precisión:



import java.math.BigDecimal;

import java.math.RoundingMode;

import java.text.NumberFormat;



RoundingMode RM = RoundingMode.HALF_EVEN;

BigDecimal amount = new BigDecimal("0.70");

BigDecimal taxPercent = new BigDecimal("0.05");

BigDecimal tax = amount.multiply(taxPercent).setScale(2, RM);

BigDecimal taxedTotal = tax.add(amount).setScale(2, RM);



NumberFormat money = NumberFormat.getCurrencyInstance();

System.out.println("Subtotal: "+ money.format(amount));

System.out.println("Tax: " + money.format(tax));

System.out.println("Tax+Total: " + money.format(taxedTotal));


Subtotal: 0,70 €

Tax: 0,04 €

Tax+Total: 0,74 €



Referencia:

http://www.javamexico.org/blogs/luxspes/por_que_usar_bigdecimal_y_no_double_para_calculos_aritmeticos_financieros

http://speleotrove.com/decimal/decifaq1.html#tzeros

http://www.mkyong.com/java/how-do-calculate-monetary-values-in-java-double-vs-bigdecimal/

http://blogs.oracle.com/CoreJavaTechTips/entry/the_need_for_bigdecimal

http://stackoverflow.com/questions/7539/please-explain-the-use-of-java-math-mathcontext/7561#7561

http://en.wikipedia.org/wiki/Floating_point

» Leer más, comentarios, etc...

Bitácora de Javier Gutiérrez Chamorro (Guti) » Programación

Código nativo y dispositivos móviles

Enero 21st, 2012

El panorama actual de dispositivos móviles, ha quedado, podríamos decir que reducido a iOS de Apple, Android de Google, y Windows Phone de Microsoft (con el permiso del marginal TabletOS de RIM). La evolución ha llevado a que el código bytecode sea el que domine estas plataformas. Java para Android, y .NET para Windows Phone. [...]

Artículos relacionados:
Rendimiento de dispositivos móviles
Office 2007 no es nativo x64
Código automodificable en PHP

» Leer más, comentarios, etc...

Javier Pérez

¿Eres inteligente? Relación entre el cociente intelectual y comportamientos e ideas del ser humano

Enero 20th, 2012

Tendencia al suicidio = Menos inteligente

Un estudio realizado por investigadores de varias universidades del mundo, sobre informes médicos de 24 años referentes a más de un millón de hombres, relaciona el cociente intelectual con la falta de tendencia al suicidio. Es decir, que las personas con más tendencias suicidas suelen tener menor cociente intelectual, sin capacidad para enfrentarse a los problemas o eventos traumáticos.

Conservador y religioso = Menos inteligente

Los más inteligentes suelen tender a probar cosas nuevas. 14.000 adolescentes norteamericanos evaluados en 2001 y 2002 dan como resultado esta relación entre ser conservador y la falta de inteligencia.

Usar Internet Explorer = Menos inteligente

Un estudio muy controvertido y cuya veracidad o autoridad está en entredicho, relaciona el uso del navegador de Microsoft, Internet Explorer, y la falta de cociente intelectual.

Consumir drogas = Más inteligente

El estudio sobre esta relación comenzó en 1970, del Estudio Británico de Cohorte, realizando un seguimiento a miles de niños (5-16 años) durante décadas hasta que cumplieron los 30 años.  Este estudio venía a demostrar también que los más inteligentes son más propensos a probar y experimentar cosas nuevas.

Hermano mayor = Más inteligente

Este estudio revelaría que los hermanos mayores son estadística y significativamente más inteligentes que sus hermanos pequeños (análisis de 241.310 hombres de 18-19 años). Se concluye además que por ese motivo los hermanos pequeños suelen ser más simpáticos, porque tratan de competir con su hermano mayor por otras vías.

Te gusta música clásica = Más inteligente

Un estudiante de doctorado del Instituto de Tecnología de California ideó un sistema para calcular una estadística que relacionara los gustos musicales con el nivel intelectual, en base a los datos de Facebook de estudiantes de diferentes universidades americanas, contrastándolos con sus notas académicas. El resultado fue que los que decían que Beethoven era su músico preferido eran los más inteligentes, y los menos inteligentes los que les gustaba el RAP o el reguetón.

Hombre fiel y ateo = Más inteligente

Este estudio también hace incapié en la falta de fé religiosa, además de en la fidelidad en la pareja, como síntoma de más inteligencia, estadísticamente hablando.

Cerebro en desarrollo = ???

Y si aún no ha terminado la edad de desarrollo cerebral (hasta los 18-20 años), ten en cuenta que tu cociente intelectual aún puede variar, y no necesariamente a más inteligente…

» Leer más, comentarios, etc...

Bitácora de Javier Gutiérrez Chamorro (Guti) » Programación

Java 8, Eclipse 4.2 y Netbeans 7.1

Enero 19th, 2012

Sin ser un gran defensor de Java a pesar de haberlo tocado bastante durante sus comienzos, debo reconocer que a día de hoy, Java es una plataforma madura, que le ha llevado a tener un rendimiento aceptable (teniendo en cuenta que es bytecode), y un nivel de estabilidad elevado. El garbage collector funciona correctamente, podría [...]

Artículos relacionados:
Eclipse solar
Sieve en Java
La historia de Java se parece al descubrimiento de América

» Leer más, comentarios, etc...

Koalite's blog

EventHandlers con jQuery 1.7: on() vs click()

Enero 19th, 2012

En la última versión de jQuery han intentado unificar las APIs de manejo de eventos en los métodos on y off. Estos métodos sustituyen a los antiguos bind(), delegate() y live().

Si comparamos el uso de on() con el de atajos que ya existían, como click(), tenemos el siguiente código:

// Asignar un manejador de eventos usando click
$("#header a").click(function() {
    // manejar el evento
});

// Asignar un manejador de eventos usando on
$("#header a").on("click", function() {
    // manejar el evento
});

Estas dos construcciones son equivalentes, pero on() permite hacer muchas más cosas. Una de las cosas que más me gusta es que permite usar un mismo manejador de eventos para múltiples elementos html suscribiendo el manejador a un elemento padre. Para ver lo que significa este lío de frase, es mejor ver un ejemplo. Supongamos que tenemos este código:


Si por algún oscuro motivo queremos asignar el mismo manejador de eventos a todos los elementos , podemos hacerlo de la siguiente forma:

$("#content").click("click", "a", function() {
    // manejar el evento
    // $(this) apunta al  que ha generado el evento
});

Esto tiene varias ventajas:

Nota para los que usamos demasiado C#

Si, al igual que yo, usas mucho C# u otro lenguaje estático, es posible que se te haga raro este tipo de API. En C#, la diferencia entre usar un API como element.click() y otra como element.on("click",...) es que la primera es type-safe y refactor-friendly, mientas que la segunda se basa en el uso de un magic string.

Sin embargo, no hay que olvidarse que esto es Javascript y es dinámico. Es igual de “seguro” (o inseguro, según se mire), escribir person.name que person["name"], por lo que el uso de magic strings es algo normal, frecuente y que hay que ver como una característica del lenguaje de la que aprovecharnos, no como una limitación.




Compartir enlace:
Facebook Twitter Email

Posts relacionados:

  1. Tutorial node.js + express + jquery (III): Usando jQuery

» Leer más, comentarios, etc...

Escuela De Codigo

Side Project, es bueno trabajar en algo propio.

Enero 19th, 2012

Un Side Project, es en palabras simples, un proyecto, invento, experimento que hago sencillamente porque tengo las ganas y el tiempo para hacerlo. ¿Porque trabajar en algo que aparentemente no nos dara ningún beneficio ya que nadie nos paga por hacerlo? Es lo que descubriremos en este articulo. 

La rutina matara tu pasión por programar

Llega un momento en la vida de todo desarrollador, que se levanta una mañana y se da cuenta que esta haciendo exactamente lo mismo que el día anterior, y que el día siguiente hara lo mismo, y la siguiente semana sera igual y peor aun es posible que el siguiente mes la mayor variación con la que se encuentre sera…posiblemente nada. Los programadores también caemos en rutinas, y para mi al menos, no hay peor rutina que la que implica: programar en el mismo lenguaje, en la misma plataforma, en el mismo IDE, en el mismo sistema operativo, resolviendo los mismos problemas con las mismas soluciones. Es un completo fastidio!!! Asi como la rutina mata el amor entre una pareja, también matara tu amor por tu trabajo, por programar. Y no queremos eso ¿cierto?

Vuelve al primer amor, trabaja en un Side Project

Si en tu trabajo son como autómatas siguiendo un manual escrito en piedra, sin ninguna posibilidad de cambiar algo, y si ahí se programa en Java así se hara toda la vida hasta que un nuevo profeta diga que hay que usar otra cosa. Dejame decirte que la única posibilidad para romper tu rutina, es creando, uno o varios Side Project, tu sabes, pequeños proyectos en paralelo que llevas por diversión, por curiosidad, cosas que programas solo para experimentar, para probar ese nuevo framework, esa nueva librería, ser atrevido.

La esencia de un Side Project es básicamente crear una pieza de software con el único proposito de ser el amo y señor de nuestro minúsculo universo, hacer las cosas como yo digo, como yo creo que es correcto, como yo quisiera que fuera correcto. Hacer algo con mis propias manos, sin que nadie me diga como hacerlo, sin cumplir requerimientos, sin seguir ordenes!! mas que las que me dicta mi propia mente.

¿Quieres probar esa nueva librería que en el trabajo y en los proyectos de la universidad no te dejan? Hazlo!!! Es TU proyecto ¿Quien te va a decir que no?

¿Quieres probar esa nueva metodología de desarrollo que tanto lees en sitios web y blogs? Hazlo!!! Es TU proyecto. Recuerda eres el amo y maestro.

Cuando tenemos una fin de semana espectacular, el lunes que regresamos a trabajar no se siente tan mal. Lo mismo es cuando has trabajado en un proyecto propio. Regresar a la rutina se hace mas llevadero.

¿Y que gano con hacer un Side Project?

Básicamente:

Ahora ya lo sabes, olvídate por un segundo de tus clientes, de tu trabajo. Deja de pelear guerras ajenas por un momento y construye algo propio. Diviértete, experimenta, aprende y quien sabe si lo que hagas sea el siguiente Twitter, uno nunca lo sabe.

» Leer más, comentarios, etc...

Fetishcode

ADF Skin Editor. Apuntes

Enero 18th, 2012

A

» Leer más, comentarios, etc...

monocaffe

Sharing Apache Tomcat and Apache Web Server

Enero 17th, 2012

Today's problem is sharing one single virtual host with different Tomcat instances. For example, say you have your Apache (the web server) with a virtual host for intranet and you have in different Tomcat instances different applications like: monitoring, dashboard and hradmin. You want your users to be directed to the correct application if they access the URL http://intranet/dashboard or http://intranet/hradmin.



In this example I'm using three Tomcat servers and this applications:





The server1 Tomcat is running two different applications and the hr1 and hr2 are running the hradmin application which we want to be load balanced and since it's critical, to be always available.



The first thing to do is create the jkworkers.properties file:



# This names are the ones defined bellow

worker.list=server1,hrlb

worker.lock=P

worker.status.type=status



# Single server running monitoring and dashboard

worker.server1.type=ajp13

worker.server1.host=192.168.1.2

worker.server1.port=8080

worker.server1.disabled=false

worker.server1.socket_timeout=60000

worker.server1.connect_timeout=60000



# Two workers for two servers running a critical application

worker.hr1.type=ajp13

worker.hr1.host=192.168.1.3

worker.hr1.port=8080

worker.hr1.disabled=false

worker.hr1.socket_timeout=60000

worker.hr1.connect_timeout=60000



worker.hr2.type=ajp13

worker.hr2.host=192.168.1.4

worker.hr2.port=8080

worker.hr2.disabled=false

worker.hr2.socket_timeout=60000

worker.hr2.connect_timeout=60000



# Loadbalancer configuration for the critical application

worker.hrlb.type=lb

worker.hrlb.balance_workers=hr1,hr2

worker.hrlb.sticky_session=true

worker.hrlb.sticky_session_force=false

worker.hrlb.method=R



Of course, you should use the DNS names instead of the IP addresses. Also, there are many more options to be set here, but this should give you a good start.



Second, you need your jk.conf file:



JkWorkersFile /etc/apache2/conf.d/jkworkers.properties

JkLogFile /var/log/apache2/mod_jk.log

JkLogLevel info

JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"

JkOptions +ForwardKeySize +ForwardURICompatUnparsed -ForwardDirectories

JkRequestLogFormat "%w %V %T"

JkShmFile /var/log/httpd/jk.shm

<Location /jkstatus>

JkMount status

    Order deny,allow

Deny from all

Allow from 127.0.0.1

</Location>



And finally, you can set up your virtual host in the, for example, intranet.conf file:



<VirtualHost *:80>

ServerName intranet

RewriteEngine on



  # Here we set where we want the url http://intranet/ to go

RedirectMatch ^/$ /dashboard/



DocumentRoot /srv/www/htdocs/docroot

CustomLog /var/log/apache2/access_reports combined

ErrorLog /var/log/apache2/error_reports



  # You can even setup a jongo proxy

ProxyPass /jongo/ http://192.168.1.5:8080/jongo/

ProxyPassReverse /jongo/ http://192.168.1.5:8080/jongo/



  # It's important that this names are the same used in your Tomcat

JkMount /dashboard/* server1

JkMount /monitoring/* server1

JkMount /hradmin/* hrlb

</VirtualHost>



What we're doing here is telling the Apache server to listen on port 80 for all requests to the intranet host and to forward this requests to their corresponding applications:





Where you put this files depends on your httpd.conf configuration.



This example will allow a vanilla Apache to serve three different applications (one load balanced) from three Tomcat servers (server1, hr1 and hr2)

» Leer más, comentarios, etc...

Fetishcode

TreeTable Editable

Enero 17th, 2012

A

» Leer más, comentarios, etc...

Variable not found

Introducción a SignalR (I): Conceptos básicos

Enero 17th, 2012

Uau!!Una aplicación que mezcla internet, asincronía, y múltiples usuarios colaborando e interactuando al mismo tiempo siempre es merecedora de un “¡uau!”. Seguro que, al igual que un servidor, en algún momento os habéis quedado maravillados con la interactividad que presentan algunos sistemas web modernos, como Facebook, Google Docs, o muchos otros, en las que estamos recibiendo actualizaciones, prácticamente en tiempo real, sin necesidad de recargar la página.



Por ejemplo, en Google Docs, si estamos editando un documento online y otro usuario accede al mismo, podemos ver sobre la marcha que ha entrado, e incluso las modificaciones que va realizando sobre el documento. O algo más cotidiano, en un simple chat vía web van apareciendo los mensajes tecleados por nuestros compañeros de sala como por arte de magia. Ambos sistemas utilizan el mismo tipo de solución: el envío asíncrono de datos entre servidor y clientes en tiempo real.



En esta serie de artículos veremos cómo podemos implementar sorprendentes funcionalidades de este tipo utilizando SignalR, un framework open source desarrollado por gente del equipo de ASP.NET, que nos facilitará bastante la tarea.

¿Cómo puede el servidor enviar eventos al cliente de forma asíncrona?

Crear este tipo de sistemas usando herramientas convencionales nos puede causar algunos dolores de cabeza, principalmente porque los protocolos que sustentan la web están basados en un modelo cliente-servidor síncrono: uno o varios clientes realizan una conexión hacia el servidor y le transmiten una acción a realizar, éste la procesa y les retorna la respuesta, cerrándose la conexión de forma inmediata.



PollingA priori, no hay forma de que el servidor sea el que notifique a los clientes los cambios de estado (por ejemplo, la llegada en un chat de un mensaje procedente de otro usuario), salvo que éstos utilicen un mecanismo de polling, es decir, que estén continuamente estableciendo conexiones con el servidor para ver si hay algún nuevo evento a tener en cuenta.



Aunque válido en determinados escenarios, hay otros en los que se trata de una solución demasiado costosa, sobre todo cuando hay que gestionar un alto número de clientes conectados.



El ideal sería utilizar una conexión persistente, siempre abierta, entre cliente y servidor, que permitiría el envío y recepción de mensajes y eventos de forma bidireccional entre ambos. De esta forma, si el servidor tiene algo que enviar a sus clientes, simplemente tendría que transmitirlo por el canal que mantendría abierto con cada uno de ellos.



Conexión persistenteSin embargo, hasta ahora esto sólo se podía conseguir usando sockets, lo cual, en entorno web, requería la existencia de algún tipo de elemento activo sobre la página (Silverlight, Flash, o applets Java, por ejemplo) capaz de establecer este tipo de comunicaciones.



Afortunadamente, la W3C parece dispuesta a cambiar esta situación al introducir de forma nativa los famosos WebSockets, cuya definición se encuentra todavía en borrador. Esta nueva API permitirá abrir conexiones directas desde el navegador usando Javascript, por lo que podría ayudarnos bastante una vez su implementación sea universal en los agentes de usuario. De momento no es así, aunque ya está disponible en algunos de ellos (podéis ver una demo simple aquí con Chrome).

Logo de HTML5

También existe otra iniciativa de la W3C que podría ayudar a enviar mensajes o eventos desde el servidor a los clientes suscritos, llamada Server-Sent Events. Como en el caso anterior, se encuentra en borrador, aunque ya algunos navegadores lo implementan (podéis ver una demo aquí con Chrome), por lo que todavía no podemos utilizarla de forma segura.



Por esta razón, existen hoy en día múltiples soluciones que permiten solventar las limitaciones del protocolo, como las englobadas bajo la denominación Server push o Comet, aprovechando los recursos existentes en los protocolos utilizados para crear, o al menos simular, este canal abierto continuo entre cliente y servidor utilizando polling, long polling, HTTP streaming, y otros artificios.



Long pollingPor ejemplo, el mecanismo long polling utiliza peticiones HTTP para crear una conexión “pseudopersistente”. El servidor, en lugar de procesar la petición y retornar la respuesta de forma inmediata, espera hasta que haya disponible algún evento o mensaje a enviar al cliente; en este momento, lo retorna como respuesta a la petición original y cierra la conexión. El cliente, por su parte, procesa esta respuesta y realiza inmediatamente después una nueva petición al servidor, que volverá a quedar abierta a la espera de mensajes, y así sucesivamente.



En definitiva, se trata de un mecanismo más limpio y eficiente que el polling, puesto que evita gran cantidad de peticiones absurdas que se producen cuando en el servidor no hay eventos pendientes de notificar. Además, dado que utiliza HTTP estándar, es válida para todo tipo de agentes de usuario, y bastante amigable para proxies, filtros, firewalls y otros inconvenientes que puede haber por el camino entre los dos extremos.



Y en este punto es donde entra en escena SignalR, un conjunto de componentes desarrollados por Damian Edwards y David Fowler, miembros del equipo de ASP.NET en Microsoft, que nos abstrae de los detalles subyacentes y nos ofrece la visión y ventajas de un entorno conectado en el que podemos comunicar cliente y servidor bidireccionalmente, de forma asíncrona, y con una sencillez pasmosa. SignalR nos hace ver como si cliente y servidor estuvieran conectados de forma continua y facilita el envío de mensajes asíncronos bidireccionales entre ambos extremos.



Por último, es importante decir que SignalR no es específico para ASP.NET MVC, ni para WebForms: podemos utilizarlo con cualquier tipo de proyecto web. De hecho, incluso se puede utilizar en otro tipo de proyectos usando un servidor self-hosted :-)

SignalR, conceptualmente

SignalR ofrece una visión a muy alto nivel de la comunicación entre el servidor y los múltiples clientes que se encuentren a él conectados. Y cuando digo “alto nivel”, creedme que estoy hablando de muchos metros de altura ;-)



Como desarrolladores, trabajaremos sobre una conexión virtualmente siempre abierta: en servidor podremos detectar cuándo se ha conectado un nuevo cliente, cuándo se ha desconectado, recibir mensajes de éstos, enviar mensajes a los clientes conectados…, en definitiva, todo lo que podemos necesitar para crear aplicaciones asíncronas multiusuario.



Sin embargo, en realidad estas conexiones persistentes no existen, o no tienen por qué existir. Se trata de una abstracción creada por SignalR, que el que se encargará del trabajo sucio que hay por debajo, manteniendo la conexión de los clientes con el servidor mediante distintos mecanismos denominados “transportes”, que son el conjunto de tecnologías utilizadas para mantener crear la conexión continua, o al menos la ilusión de su existencia.



Lo interesante de los protocolos de transporte es que pueden ser sustituidos de forma transparente sin afectar a nuestras aplicaciones, que trabajarán aisladas de estos detalles. Nuestros sistemas funcionarán exactamente igual sea cual sea el transporte utilizado, lo que permite que éste sea elegido en cada escenario en función de la disponibilidad de las tecnologías en ambos extremos.



Por ejemplo, el transporte Websockets es capaz de crear una conexión con el servidor y mantenerla abierta de forma continua, aunque requiere que esta tecnología esté disponible tanto en el cliente (en el caso de clientes web, es necesario que el navegador implemente Websockets) como en el servidor.



Long polling, el transporte utilizado por defecto en SignalRDebido a ello, y para asegurar la máxima compatibilidad con los clientes, actualmente se utiliza por defecto el transporte denominado Long polling, que ya hemos comentado anteriormente.



Observad que, a pesar de la relativa complejidad que supondría implementar algo así a mano, nosotros no tendremos que hacer nada: SignalR se encarga de llevar a cabo todas estas tareas para ofrecernos la sensación de estar siempre conectados.



Su componente cliente será el encargado de realizar las conexiones, mantenerse a la espera de noticias del servidor, reconectar cuando se reciban eventos o cuando por cualquier otra causa se haya perdido la conectividad, etc., ofreciéndonos una superficie de desarrollo muy simplificada.



El lado servidor de SignalR, por otra parte, será el encargado de recibir la conexión y mantenerla en espera, almacenar los mensajes recibidos, realizar el seguimiento de clientes conectados, enviar mensajes a través de un bus interno, etc., y de la misma forma, ofreciéndonos un API bastante simple para implementar nuestros servicios.

Implementación de servicios con SignalR

SignalR nos ofrece dos fórmulas para trabajar sobre las conexiones que crea con el servidor:

En cualquiera de los dos casos, y ya centrándonos en el entorno web más habitual, donde el servidor es una aplicación ASP.NET y los clientes van a ser las páginas o vistas en las que tendremos un motor de scripting, la implementación de servicios consistirá en:

Cada una de las dos fórmulas citadas tiene sus particularidades, por lo que las estudiaremos mediante el desarrollo de ejemplos independientes en futuros posts de la serie.



Pero primero, veamos rápidamente cómo podemos incluir este componente en nuestros proyectos, aunque desde luego más sencillo no puede ser… ;-)

Instalación de SignalR

El sitio web oficial del producto (signalr.net), a día de hoy, es una simple redirección hacia Github, donde se encuentra la documentación y el código fuente del proyecto. Aunque podríamos descargarlo desde ahí, la opción más sencilla, como siempre, es utilizar Nuget:



PM> Install-Package signalr
Attempting to resolve dependency 'SignalR.Server (≥ 0.3.5)'.
Attempting to resolve dependency 'Microsoft.Web.Infrastructure (≥ 1.0.0.0)'.
Attempting to resolve dependency 'SignalR.Js (≥ 0.3.5)'.
Attempting to resolve dependency 'jQuery (≥ 1.6)'.
Successfully installed 'Microsoft.Web.Infrastructure 1.0.0.0'.
Successfully installed 'SignalR.Server 0.3.5'.
Successfully installed 'SignalR.Js 0.3.5'.
Successfully installed 'SignalR 0.3.5'.
Successfully added 'Microsoft.Web.Infrastructure 1.0.0.0' to SignalRDemo.
Successfully added 'SignalR.Server 0.3.5' to SignalRDemo.
Successfully added 'SignalR.Js 0.3.5' to SignalRDemo.
Successfully added 'SignalR 0.3.5' to SignalRDemo.


Esta instalación incluye, además de algún elemento infraestructural, dos componentes de SignalR:

Existen también otros clientes específicos para .NET, como SignalR.Client (cliente genérico), SignalR.Client.Silverlight (específico para SL), o SignalR.Client.WP7 (específico para Windows Phone 7), que podemos instalar de forma independiente.



Además, tanto en Nuget como en el sitio web del producto podéis encontrar otros paquetes interesantes a los que vale la pena echar un vistazo, como SignalR.Sample, un ejemplo completo de uso de este componente, SignalR.SelfHost, que permite activar el servidor sin usar ASP.NET, o SignalR.Websockets, un adaptador (o transporte, en argot SignalR) para usar Websockets para el mantenimiento de la conexión entre cliente y servidor.



Observaréis que en todos los casos se trata de versiones muy preliminares pero que podemos ir probando y disfrutando desde ya, porque funcionan bastante bien. Podéis comprobarlo accediendo a http://jabbr.net/, un chat implementado sobre SignalR donde podréis encontrar charlando hasta a los mismísimos padres de la criatura. :-)



En el próximo post veremos cómo implementar clientes y servicios SignalR utilizando conexiones persistentes, el enfoque de menor nivel ofrecido por este fantástico componente.



Publicado en: Variable not found.



» Leer más, comentarios, etc...

Picando Código

ArchLinux: pacman 4 en el repositorio principal

Enero 16th, 2012

pacman

pacman

Llegó la hora de actualizar nuestros sistemas operativos ArchLinux a pacman 4. En esta versión trabajaron 24 personas creando 893 commits. Pueden ver todos los cambios en este enlace. La característica más esperada de esta versión es el firmado gpg de los paquetes, algo que generó bastante controversia en su momento en la comunidad de Archers.

De todas formas, esta característica viene deshabilitada por defecto en la configuración de pacman. Esto será así hasta que se pulan algunos detalles de la nueva funcionalidad. Para probar la verificación de los paquetes, tenemos que antes darnos una vuelta por la wiki de Arch e informarnos sobre Pacman-key.

pacman 4

pacman 4

En algunas ocasiones, la actualización de pacman puede requerir intervención manual. Por ejemplo en mi sistema:

error: failed to prepare transaction (could not satisfy dependencies)
:: package-query: requires pacman<3.6
:: pyalpm: requires pacman<3.6

Al intentar desinstalar el paquete pyalpm, encontré otras dependencias hasta que pude corregir la instalación completa haciendo:

[fernando@hoth ~]$ sudo pacman -R pyalpm namcap package-query yaourt

Ya luego no hubo problemas para instalar pacman:

[fernando@hoth ~]$ sudo pacman -S pacman

Y ya con la nueva versión volví a instalar yaourt y demás :)

» Leer más, comentarios, etc...

xailer.info (esp)

Quick Open

Enero 16th, 2012

En esta ocasión traemos a un complemento para el IDE similar a SessionManager SessionManager, pero que en vez de manejar grupos de archivos como sesiones nos permite filtrar y abrir archivos de un proyecto rápidamente.

Al seleccionar la opción del menú:

Quick open menu

Se lanza un formulario que contiene un control de edición y la lista de archivos que forman parte del proyecto.

En el control de edición se puede escribir una máscara para filtrar los archivos. Se permite el uso de comodines como ? y * y su funcionamiento es idéntico a la función Directory() estándar de Harbour.

Quick open

En la lista de archivos se pueden seleccionar más de uno con Ctrl+Click o varios seguidos con Shift+Click/Shift+Cursores. Su funcionamiento es idéntico a un control Listbox estándar.

Haciendo doble click o pulsando [Enter] sobre el nombre de un archivo se abrirá en el editor de código o se seleccionará si ya estaba abierto. Si hay varios archivos seleccionados al pulsar [Enter] se abrirán todos en el editor.

Si se cambia a otro proyecto, al hacer click en el formulario se recarga automáticamente la lista de archivos del nuevo proyecto por lo que no es necesario cerrar y volver a abrirlo para actualizarlo.

El formulario se puede redimensionar y mover al lugar de la pantalla que se prefiera y su posición y tamaño será recordado la próxima vez que se utilice.

El plugin sólo funciona con Xailer 2.5 y Xailer 2.5.1

El enlace para la descarga: QuickOpen

» Leer más, comentarios, etc...

Información legal y técnica