viernes, 14 de enero de 2011

Página oculta de la impresora HP Deskjet 3050 WI-FI

Hola muy buenas,
Me animo a escribir este nuevo post para hablar un poco sobre un problema que me encontré con la impresora multifuncional HP Deskjet 3050 WI-FI. Como veis, esta entrada no tiene nada que ver con las pocas cosas que estoy escribiendo sobre problemas y soluciones de programación que no conseguimos encontrar en Internet.

Escribo esta entrada porque ayer mismo me sucedió que mis padres estaban un poco descontentos con esta impresora multifuncional, debido a que cada vez que se enciende la máquina y de manera aleatoria, se conecta a la red inalámbrica que tengo en casa, obligándome en muchos casos a tener que enchufarla al puerto USB para poder imprimir. Claro, en ese momento se preguntan mis padres que para qué diablos compraron una impresora WI-FI. Además, como en nuestros hogares domésticos, no siempre pueden estar la impresora junto al ordenador, por motivos de espacio y en principio, la tecnología WI-FI solventa este problema. En mi caso la impresora se encuentra en el cuarto de mis padres y el ordenador en el salón. Ya ven ustedes la incomodidad que supone cuando no se conecta la impresora correctamente a la red, tener que coger la máquina para conectarla al USB del ordenador.



Observando que cuando conectaba la impresora por USB, y esta se conectaba a la red, podía desconectar tranquilamente el cable USB y la impresora seguía imprimiendo. Además lo más curioso es que la apagaba y la encendía de nuevo y funcionaba. Pues bien, al desenchufar la impresora perdía la información. En ese momento me voy a ver las instrucciones de la máquina y en todo momento me dicen que debo conectar la impresora a mi red WI-FI mediante un software que se instala en el ordenador y para ello es necesario conectar el cable USB. En otras palabras, la pescadilla que se muerde la cola.

En este momento paso a explicar el procedimiento que seguí y que no he conseguido encontrar ni en las instrucciones de la impresora, ni tampoco en google.
Repito el proceso para conectar mi impresora a la red WI-FI mediante el cable USB tal y como se explica en el manual. Si es cierto que en los manuales de la impresora aparece o hace mención que nuestra red debe tener el filtro MAC desactivado o bien, incluir la dirección MAC de la impresora a la lista de direcciones MAC permitidas.

Apunto la dirección MAC y seguidamente entro en el router. Observo que el router le ha asignado una dirección IP a la impresora.
Desconecto la impresora de la alimentación y vuelvo a intentar que conecte, teniendo el mismo resultado que he explicado antes. En este caso siempre aparece la luz azul parpadeando. Entro en el router y busco la MAC de mi impresora. Curiosamente la impresora ha accedido a la red. Entonces ¿Por qué parpadea la luz azul y me dice que no está conectada? La respuesta es que no ha podido el servidor DHCP asignar una dirección IP a la impresora.
¿Qué hacemos? Aquí en este punto es donde tampoco explica el manual que hacer en este caso porque simplemente es que no expone el problema.
Repetimos el paso este de conectar la impresora al USB y conectarla a la WI-FI. Buscamos la MAC de la impresora y apuntamos su IP.


Desde un navegador Web, introducimos su IP y curiosamente, esta impresora tiene internamente un servidor Web que nos permite hacer un montón de cosas, tales como escanear desde la Web, ver el nivel de tinta, imprimir y configurarla. (Sinceramente esta página no aparece en el manual).


Nos vamos a configuración de red, y entre otras opciones podemos ver que nuestra impresora funciona también como punto de acceso. Impresionante ¿verdad? Tampoco se explica en el manual.


Pues nos dirigimos a la sección de configuración TCP/IP, y ahí mismo podemos asignar una IP estática a esta impresora. Configuraremos la IP estática más adecuada a nuestra red. Para ello aconsejo buscar en google como hacerlo porque hay miles de páginas que lo explican. Otro detalle es que pide IP de ruta de enlace (router) y servidores DNS. ¿Para que quiere nuestra impresora un servidor DNS? ¿Será para que controlen la obsolencia planificada de nuestra impresora? O ¿será para otros fines que desconocemos? No entiendo porqué la impresora debe tener salida a Internet y resolver direcciones IP. Por favor, si alguien tiene alguna pista de esto, que lo exponga aquí mismo. (Tampoco se explica en el manual).
A partir de este momento en el que nuestra impresora tiene configurada una IP estática, podemos encenderla, apagarla, desconectarla, o cualquier tipo de combinación, que la luz azul que parpadeaba indicando que la impresora no estaba conectada, estará siempre fija.

Espero que les sirvan de ayuda. Por favor, si sabéis algo del porqué necesita saber la impresora los servidores DNS, que lo escriban aquí.

lunes, 3 de enero de 2011

Solución a problemas de cache de ficheros javascript.

Hola muy buenas,

Después de estar algún tiempo sin escribir en mi blog, hoy pienso plantear un problema que se presenta en el desarrollo de páginas web y que tantas soluciones existen. Yo particularmente, voy a presentar mi solución basado en ASP.Net.

En mas de una ocasión tenemos un proyecto web, en el que nos surge una incidencia con respecto a un fichero javascript de nuestra aplicación y por tanto debemos cambiar el código de dicho fichero javascript sin necesidad de alterar el contenido del resto de páginas web. Después de realizar pruebas y pruebas, decidimos que nuestro código se encuentra en una versión estable y decidimos pasar a producción los cambios realizados. Al poco rato, nos llama nuestro cliente diciendo que la página no funciona, por tanto volvemos a revisar nuestro código y resulta que el código si que está funcionando. Nos dirigimos a otra máquina para comprobar el error, y vemos que igualmente funciona. Entonces podemos preguntarnos ¿que le está ocurriendo al cliente? ¿tendrá algún software maligno que le impida ejecutar nuestros cambios? La respuesta es no.
El problema es que el navegador del cliente ha cacheado el fichero javascript que hemos modificado, y al publicar la nueva versión del proyecto en el servidor y su navegador, que ya tenía una copia local del antiguo fichero javascript, cree que este fichero no ha cambiado porque la página que usa este código tampoco ha cambiado.
Entonces, ¿como solucionamos el problema? podemos decirle al cliente que elimine la caché y vuelva a cargar la web, pero sin embargo, esto no es una solución del todo elegante, pues el cliente no tiene porque realizar esta operación cada vez que hagamos un cambio. Por otro lado, podemos tener la precaución de cambiar algo en la página que usa este fichero javascript para que los navegadores desechen de la caché el fichero javascript, pero sin embargo, es una tarea que es propensa a que se nos olvide, o mejor aún, puede existir miles de páginas que usan nuestro fichero javascript y es tedioso cambiar todas antes de publicar nuestra nueva versión.
¿Y que hacemos? Pues podemos utilizar este truco.

       
<script type="text/javascript"
src="mifichero.js?v=200308170900"></script>


Con este sencillo truco engañamos al navegador para que elimine de la cache el fichero. Podemos usar ese número como un número de versión que tendremos en una variable de cadena en cualquier punto del proyecto que podamos controlar y nos resulte sencillo cambiar, de tal forma que dicho cambio se propague por todas las páginas de nuestro proyecto.


Vamos a dar un paso más, para aquellos que se le olvide cambiar este número de versión, en ASP.Net podemos utilizar este pequeño trozo de código, que hará esta operación por nosotros. Cada vez que se compile una nueva versión de nuestro proyecto, se generará un nuevo ensamblado que contendrá una versión distinta a la anterior de forma automática. ¿Como consultamos esa versión? Pues con el siguiente trozo de código:


       
Assembly ase = Assembly.GetExecutingAssembly();

Label1.Text = ase.ManifestModule.ModuleVersionId.ToString();



Espero que esta entrada os sirva de ayuda. Hasta otra.

sábado, 13 de noviembre de 2010

Generador DNI, NIE y CIF.

Hola de nuevo.

Como comenté en la primera entrada de este blog, expuse una clase Java que genera documentos aleatorios. Pues bien, para aquellos que no quieran montar un proyecto para generar algunos documentos de pruebas, aquí les paso la dirección de una herramienta que he subido a la web.

http://niednicifgenerador.appspot.com/

Esta herramienta es perfecta para aquellos casos en los que queremos generar algún tipo de presupuesto, como puede ser por ejemplo un presupuesto para el seguro del coche, en el que la web de seguros solicita entre otros datos un D.N.I. para poder continuar el proceso de presupuestado y poder obtener el valor final de la póliza de seguro.

En ningún momento creo que sea necesario que la compañía tenga nuestra información entre ellas la del D.N.I. para poder hacer un presupuesto válido, eso si en el momento que decidamos realizar la contratación, obviamente deberán de tener nuestro D.N.I. verdadero.

Por ejemplo, si pedimos presupuesto de seguro en un teléfono rojo con ruedas, se puede ver que ofrecen como excusa barata la posibilidad de acceder a tu información a través de tu número de D.N.I.  cuando previamente ya nos habían preguntado por una dirección de correo electrónico. ¿No nos pueden enviar un enlace de acceso a nuestra información por correo electrónico? No me gustaría pensar que una persona que se conozca nuestro D.N.I. pueda acceder a los datos que hemos facilitado en dicha compañía, ya que según el mensaje nos hace pensar que es la clave que utilizaremos para acceder a nuestros datos (no lo sé, pero tampoco me parece que tengamos que dar un documento tan importante como nuestro D.N.I.).

En general, estas compañías utilizan dicha información entre ellos nuestro D.N.I. para fines publicitarios como por ejemplo el spam telefónico, etc. Es cierto que en todo momento estas compañías solicitan al usuario la aceptación de la ley de protección de datos, que es de obligado cumplimiento antes de recoger y almacenar nuestros datos.

Espero que les sea de utilidad.

Por último, antes de despedirme, les recomiendo que lean este libro, Acceso WiFi con el DNIe: Sistema de Control de Acceso en Redes Wireless con el DNI electrónico y software libre porque se trata de un método para conceder acceso a nuestras redes wifi mediante el DNIE.

martes, 9 de noviembre de 2010

Cierre de conexiones olvidadas


En esta entrada quiero comentar un problema muy común que puede darse en un proyecto de gran envergadura, estamos hablando de millones de líneas de código, centenares de métodos que acceden a las bases de datos, y en el que puede ser bastante común, que debido a una mala práctica de programación, estos métodos solicitan o abren una conexión a la base de datos y por despiste del programador, no se cierra.
Ante esta situación nuestro proyecto puede tener grandes problemas cuando todas estas conexiones abiertas no han sido correctamente cerradas o devuelta a un POOL de conexiones, provocando que nuestro servidor caiga debido a que pueda quedarse en un momento dado sin conexiones disponibles para ser usadas.
Según la documentación de Java, sabemos que el recolector de basura es capaz de cerrar estas conexiones una vez que detecta que estas conexiones dejaron de ser usadas.
Resumiendo las cuentas, estamos ante el escenario de que nuestro proyecto tiene un único punto donde se crean las conexiones (Pool de conexiones) y que existe código que no devuelve estas conexiones al pool, por lo que pueden quedar zombies en cualquier lugar del código. Además, para mala fortuna, no sabemos detectar en que parte del código no se devuelven al pool dichas conexiones. Este escenario se dio en un proyecto de la Consejería de Gobernación de la Junta de Andalucía, y que resolví con la solución que voy a aportar ahora mismo.
Aunque no voy a colocar el código, voy a comentar la idea para que puedan considerarla y ponerla en práctica.
Como sabemos que el punto común de la aplicación para crear u obtener conexiones es el pool de conexiones, sabemos que será aquí uno de los lugares candidatos a tener que modificar. En este punto, en vez de devolver una conexión específica (instancia de la clase que implementa java.sql.Connection), devolveremos una conexión específica nuestra que crearemos (decorador).
1.       Creamos una clase que implemente la interfaz java.sql.Connection
2.       Creamos un atributo delegado de tipo java.sql.connection (decorado) que alberga el delegado o instancia de conexión que crea el pool de conexciones. Es decir, nuestro pool devuelve una instancia de la clase que estamos creando y obligamos que la conexión real esté en este atributo delegado.
3.       Implementamos todos los métodos de la interfaz delegando al delegado cada llamada implementación.
4.       Reimplementamos el método close de nuestra clase, para que devuelva el delegado al pool.
5.       Implementamos el método finalize, que devolverá la conexión al pool si no se hizo antes esta operación. Esto es sencillo de saber, basta con colocar un atributo booleano para saber si se invocó el método close.
6.       En el constructor de nuestra clase, obligamos a llamar al recolector de basura con System.gc() cada ciertas conexiones abiertas o creadas, de tal forma que el recolector de basura, llamará al método finalize de cada conexión que no se esté usando, y esta a su vez devolverá el delegado al pool.
Como veis, esta solución es un poco rebuscada, de hecho en mi empresa se plantearon de crear herramientas para detectar cuantas conexiones no se cerraban. Sin embargo, con esta solución ahorré dinero y tiempo, y conseguimos el objetivo deseado (no más caídas del sistema por falta de conexiones).
Disculpad por no aportar el código, pero creo que es más importante conocer la idea, que el código en sí, puesto que para cada proyecto, el código puede variar. Lo importante es conocer el diseño de la solución.
Si tenéis cualquier tipo de dudas, no tengáis reparo en poneros en contacto con migo para que os ayude en esta solución.

viernes, 5 de noviembre de 2010

Introducción a mi apertura del blog.

Hola muy buenas,

Para los lectores que encuentren este blog por Internet, quiero pedirles de antemano disculpas debido a que por numerosas razones no voy a poder tener muy actualizado este blog. Entre otras es porque pretendo utilizar este blog para aportar soluciones e ideas que realmente sean de calidad. No quiero que este blog sea una página más que encontramos en google con el recurso que estamos buscando, si no mas bien mi idea es que este blog sea la solución ingeniosa que no hemos encontrado en ningún lugar en el momento que se publicó la idea.

Antes de nada, quiero presentarme. Soy un Ingeniero en Informática de Sevilla, que ha tenido suerte de trabajar en proyectos .Net para empresas como Arrakis/BT, el Ayuntamiento de Sevilla entre otros. Actualmente y a fecha que publico esta entrada participo en proyectos J2EE para la Consejería de Gobernación y Justicia de la Junta de Andalucía.

En todo este tiempo de experiencia me han surgido ideas reconocidas por altos cargos de la empresa donde trabajo (EVERIS), sobre ideas que comentaré más adelante.

También comentaré ciertos trozos de código que he bicheado por la red, y que he perfeccionado, haciendo referencia a estas entradas. Obviamente, como dijo Newton, avanzo a "hombros de gigantes".

Bueno, no me enrollo más. Espero que les sea de utilidad las publicaciones que haga.

Un saludo.