Picando Código
¿Y si juntamos a la comunidad de usuarios ArchLinux del Uruguay?
Enero 26th, 2012
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.
- Aprender a empaquetar aplicaciones y buscar alguna aplicación que podríamos enviar a AUR. Es un conocimiento que viene bien, y seguramente todos han toqueteado algún PKGBUILD en algún momento. De repente sale algo interesante.
- Ayudar con la traducción de la wiki, si alguien tiene algo de tiempo libre para aportar al proyecto, esta es una buena manera. (más ideas acá)
- Dar a conocer cosas interesantes que hayamos logrado, scripts, personalizaciones, etc. Ayudar con algún problema particular que algun usuario pueda tener con el sistema.
- “Evangelizar” a usuarios de otras distros, ayudarles a darse cuenta que ArchLinux es la mejor distribución de GNU/Linux

- Comprar camisetas de ArchLinux. Al ser muchos, podemos conseguir un buen precio para mandar a hacer camisetas de Arch.
- DRY: No repetirnos. No hay que reinventar la rueda, crear más wikis y demás información repetida. Creo que si en algún momento armamos alguna representación virtual del grupo en internet, habría que limitarse al tema de las reuniones y demás posibles organizaciones que podamos llevar a cabo. Nada de reescribir o copiar y pegar todo el conocimiento que tan bien documentado está en la wiki de Arch.
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:
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:
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.
No hay posts relacionados.
» Leer más, comentarios, etc...
Arragonán
Don’t Censor Me!
Enero 26th, 2012

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.

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.

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:

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
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.
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:
- “Putting Dependency Injection on the map” contiene tres capítulos introductorios, útiles para poner en contexto el patrón y las ventajas que conlleva su uso y describir los conceptos fundamentales utilizados: dependencias, tipos, tiempo de vida, intercepción, contenedores, y muchos otros.
- “DI catalog” es una completa relación de patrones de uso de la inyección de dependencias, antipatrones o malos usos que podemos hacer de la misma, y refactorizaciones que podemos utilizar para solucionar escenarios frecuentes.
- “DIY DI” describe técnicas asociadas a la ID, como la composición de objetos, la gestión del ciclo de vida, y la intercepción de llamadas.
- “DI containers” es un completo bloque donde se describe el uso de los principales contenedores disponibles para la plataforma .NET: Castle Windsor, StructureMap, Spring.NET, Autofac, Unity y MEF.
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:
- mediante conexiones persistentes, la opción de menor nivel, que proporciona mecanismos de notificación de conexión y desconexión de clientes, así como para recibir y enviar mensajes asíncronos a clientes conectados, tanto de forma individual como colectiva.
- mediante el uso de “hubs”, que ofrece una interfaz de desarrollo mucho más sencilla, con una integración entre cliente y servidor que parece pura magia, y que seguro será la opción más utilizada por su potencia y facilidad de uso.
Bueno, 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:
- 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.
- Registraremos este endpoint durante la inicialización de la aplicación, asociándole una URL de acceso a las funcionalidades del servicio.
- 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.
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 deSignalR.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:
- tomar el control en el momento en que se produce una nueva conexión (método
OnConnected), momento en que enviaremos al resto de clientes un mensaje con información sobre el cliente conectado y el total de conexiones activas. - tomar el control en el momento en que se produce la desconexión de un cliente (método
OnDisconnect()), para notificar al resto y actualizarles el número de clientes conectados.
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étodoOnConnected() 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 virtualOnDisconnect() 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étodoOnConnected() 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:
- desde el cliente, una vez se ha realizado la conexión, realizar un envío de datos al servidor, algo similar a un “ping”,
- en el método
OnReceived()del servidor, capturar el mensaje enviado desde el cliente y responderle de forma directa con la información que nos interese hacerle llegar, que podría ser un mensaje de bienvenida y, como en otras ocasiones, el número de usuarios conectados:protected override void OnReceived(string clientId, string data) { var msg = new NotificationMessage("Hi!", _clients.Count); Send(clientId, msg); }
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: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:
“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”
<h2>Log</h2> <div id="log"></div>A continuación, necesitamos implementar el código de script que realice las siguientes tareas:
- iniciar la conexión con el endpoint,
- tras ello, enviar un “ping” para recibir el mensaje de bienvenida (recordad lo que os comentaba previamente de que el broadcast no se recibe por el cliente que inicia la conexión),
- mostrar en el log la información recibida del servidor.
<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:- en la variable
connobtenemos una referencia hacia el endpoint, identificado por el nombre de la conexión persistente, en este caso,VisitorsService. - sobre ella, definimos la función
received(), que será invocada cuando el servidor envíe información. El parámetro que recibe la función anónima es la información enviada desde el servidor, que, recordaréis, en este caso se trataba en objetos de tipoNotificationMessage. Dado que la serialización y deserialización se realizan de forma automática, podemos acceder directamente a sus miembros, como podéis ver en el código para montar el mensaje e introducirlo en el log. - por último, iniciamos la conexión invocando al método
start()de la conexión. Observad que este método admite un callback que será llamado cuando la conexión se haya establecido, momento que aprovechamos para enviar el “ping” al servidor que nos permitirá recibir el mensaje de bienvenida.
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.
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

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:
- Sólo se crea una única función, independientemente del número de elementos
que tengamos, reduciendo el consumo de recursos. - Es válido para elementos que no existen todavía. Si apareciese un nuevo elemento
dentro del, automáticamente estaríamos manejando su eventoclick. Esto es especialmente útil cuando generamos html dinámicamente.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 comoelement.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.namequeperson["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.Posts relacionados:
» 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:
- Salir de tu aburrida rutina como programador! Si ya estas harto de programar lo mismo un día tras otro. Pues si tienes un proyecto personal podrás hacer lo que se te venga en gana. No rutinas aburridas.
- Experimentación, si eres de los que tiene miedo de hacer algo con el codigo de la empresa por temor a arruinarlo todo, en tus proyectos no tienes de que preocuparte, si algo falla, no se destruira el mundo no te preocupes.
- Aprendizaje, con los errores cometidos, viene la sabiduría. Aprenderas mucho de como hacer algo o como no hacerlo.
- A tu manera, todo lo harás siguiendo las ordenes de una tan sola persona: tu.
- Algo mas para tu curriculum, si lo que hagas te parece muy bueno, porque no hacerlo publico y mostrarlo a todo mundo.
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:- server1:8080/monitoring/
- server1:8080/dashboard/
- hr1:8080/hradmin/
- hr2:8080/hradmin/
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:- http://intranet/ goes to http://server1/dashboard/
- http://intranet/dashboard/ goes to http://server1/dashboard/
- http://intranet/monitoring/ goes to http://server1/monitoring/
- http://intranet/hradmin/ goes to http://hr1/hradmin/ or to http://hr2/hradmin/
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
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.
A 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.
Sin 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).

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.
Por 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.
Debido 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:
- usando “conexiones persistentes”, es la de más bajo nivel y proporciona mecanismos simples para registrar conexiones y desconexiones de clientes y comunicarse de forma bidireccional con ellos. De hecho, esta forma de crear servicios es bastante similar a como hacemos utilizando sockets.
- usando “hubs”, que ofrece una abstracción aún mayor, permitiendo la comunicación entre cliente y servidor de forma casi mágica. Esta es la opción que convendrá utilizar en la mayoría de ocasiones, por la potencia que aporta y su gran comodidad de uso.
- en el servidor, crear el servicio (también llamado endpoint) con las funcionalidades que nos interese, utilizando las clases disponibles en el ensamblado SignalR.
- en cliente, crear el consumidor del servicio utilizando las clases disponibles en la biblioteca de scripts jQuery.SignalR.js (o su correspondiente versión minimizada).
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:
- SignalR.Server, que es la biblioteca de servidor principal para integrar en aplicaciones ASP.NET.
- SignalR.Js, la biblioteca Javascript necesaria para conectar desde cliente (páginas web) con el servidor.
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
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.
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.6Al 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ú:

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.

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











