Carlos Ble

Carlos Ble

I am a professional software developer, I solve problems.

I also teach and mentor developers to build better software.

Working as an independent professional since 2009.

Can I help you?

  • Do you need high quality tailor-made software?
  • Need training on TDD, clean code or refactoring?
  • Is it risky? do you need advise?
  • May I pair with you to write better code?

Events

Upcoming public training courses:

  1. [in English] May 5, 6 & 7
    TDD - Train the Trainers (iSQI)
    Potsdam, Berlin
  2. [en Español] 23, 24 y 25 de Abril.
    Curso de TDD con examen de certificacion iSQI
    Madrid
  3. [en Español] 29, 30 y 31 de Octubre.
    Curso de TDD con examen de certificacion iSQI
    Madrid

Conferences:

  1. I'll be at SocratesUK 2014
  2. I'll be at the London Test Gathering Workshops.

Archive for the ‘Plumbing’ Category



WebSockets and Android

I didn't know that the default browser installed on Android is called Webview. I haven't created any native Android app ever. But I wanted my web app to run on Android using Websockets. Unfortunately, websockets are not implemented in Android Webview.

In modern browsers, HTML5 provides a websocket API:

  1.  
  2. ws = new WebSocket('ws://' + host + ':'+ port);
  3. ws.onmessage = function(msg){
  4. var data = JSON.parse(msg.data);
  5. ws.send(JSON.stringify({message: 'OK cool!'}));
  6. };
  7.  

You don't need to include any JavaScript file in order for this to be valid code in modern browsers (when I saw it for the first time I was like.... "yeah cool but what library are you using?). Well you'd need a Websocket server. I've been trying ws for Node. It works very well with express.js and is very simple:

  1.  
  2. var WebSocketServer = require('ws').Server;
  3. var wss = new WebSocketServer({server: server}); // server is express' server instance.
  4. var clients = [];
  5.  
  6. wss.on('connection', function(ws) {
  7. console.log('connected');
  8. clients.push(ws);
  9. ws.on('close', function(){
  10. console.log('client closing');
  11. });
  12. ws.on('message', function(msg){
  13. console.log('message received');
  14. for (var i = 0, len = clients.length; i < len; i++)
  15. try {
  16. // do not use try-catch here, do it properly
  17. if (clients[i])
  18. clients[i].send(msg);
  19. }
  20. catch(e){
  21. clients[i] = null;
  22. }
  23. });
  24. });
  25.  

The code above is broadcasting a message to all connected clients.

It's very nice but it doesn't work on Android!

Workarounds:

  • Install Firefox or Chrome for Android, they support Websockets
  • Use a library that supports fall back to XHR long polling like Socket.io
  • Use Apache Cordova (phonegap) to create an Android app
  • Use a Flash implementation of websockets

If you use Apache Cordova you need to "provide" the websockets funcionality into webview using Java code. There are several plugins for that:

I haven't used any of those. The disadvantage is that users have to install an application. I just want them to use my web app without installing anything so I've discarded this option.

The flash implementation has some security constraints imposed by flash. I haven't dug into the subject much but I believe I need to open port 843 on the server and I can't do that on some PAAS providers. I can't confirm this, I might be wrong. The other thing is that browser needs the flash plugin. Take a look at this implementation (web-socket-js).

Eventually I've come back to Socket.io. Although people say it's outdated and it's got a poor websockets RFC implementation, it works very well for basic stuff and falls back to XHR long polling automatically:

  1.  
  2. var io = require('socket.io').listen(server); // server is express' server instance
  3. io.configure(function () {
  4. io.set("transports", ["websocket", "xhr-polling"]); // support both
  5. io.set("polling duration", 10);
  6. });
  7.  
  8. io.sockets.on('connection', function(socket){
  9. socket.on("sendMessage", function(msg){
  10. io.sockets.emit("messageReceived", msg); // broadcasting
  11. });
  12. });
  13.  
  14.  

On modern browsers implementing websockets, it will use them. On Android it will just use long polling.

To finish off, just remember that your mobile device and your desktop pc are two separate machines. If your client side js is trying to connect to "localhost" as the websockets server, it's not going to work from your mobile. I know it's absolutely obvious but I wasted more time than I expected not realizing that I had the wrong url in the client side js. It was written "localhost" rather than "192.168.0.100" for my tests using the Local Area Network. It was one of those silly mistakes that steal one's time more than they should :-(

Configuring Targus keyboard

2013-08-17 13.15.10

Steve and Imo during a Code Kata

I've bought a new keyboard to use it with my laptop when I travel and also for coding dojos. It's small, cordless and with US layout which is what I use for coding. Very handy. It's a Targus AKB33US.

But it hasn't been easy to configure on my Ubuntu (I use lxde, known as lubuntu).

First the bluetooth... I needed to try it on Windows and also the help of my friends to get to know how to configure the bluetooth keyboard. I am using "Blueman" desktop app to configure it on Linux. And also a bluetooth-usb adapter. First you search for devices, and once the keyboard is found you select "Pair" from the right mouse button menu. Then it asks for a pin. Choose whatever you want (1234 for example) and click OK, and right after that introduce 1234 in the bluetooth keyboard.  Unfortunately Blueman doesn't tell you this but the Window's app did. Then also select "Trust" from the context menu. Then it should work.

The bad thing about Targus keyboard is that Delete and BackSpace keys are swapped and that is frustrating. This is the way to fix it on my machine.

  1. # reset key map:
  2. setxkbmap us
  3. # swap keys
  4. xmodmap -e "keysym Delete = BackSpace"
  5. xmodmap -e "keycode 22 = Delete"

Thanks to Steve and Imo for the help with the keyboard in our last code kata together.

O "de pies" que dirían en Madrid :-)

Hace años me lesioné la espalda por ignorante. Y claro, todos los días haciendo horas sentado delante de la máquina aumentan el dolor de espalda considerablemente. Puedes hacer natación, pilates (muy bueno!), puedes ir al quiropráctico, al fisioterapeuta, y...  también puedes trabajar de pie a ratos! @EtnasSoft me dijo el otro día que ya lo estaba haciendo también por problemas de espalda y que era muy recomendable. Así que lo he probado y estoy encantado!

Tengo dos mesas como se ve en la foto. Cuando me cambio de una a la otra, muevo la pantalla el teclado y el ratón. Un movimiento de

milisegundos.

 

A mis compañeros de pair programming les encanta, porque cuando me pongo en pie aprovechan para quitarme la silla enseguida :-)

Mas o menos cada 3 pomodoros me cambio de posicion. #recomendado! :-)

 

 

Esta vez toca escribir en español porque la mayoría de entradas que encontré en la red sobre Samba y máquinas Windows estaba en castellano lo cual parece indicar que es una herramienta muy usada en paises latinos.

Dentro del poco conocimiento que tengo de Samba y advirtiendo que algunas de las afirmaciones que vienen a continuación podrían ser incorrectas, describo cómo hemos resuelto los problemas de políticas usuario, perfiles e impresoras en dominios netbios que contienen equipos con Windows XP y Windows 2000.
Samba hace que un servidor Linux funcione como controlador de dominio Windows (netbios) de manera que puede enviar el perfil de los usuarios a las máquinas cliente cuando hacen login junto con políticas que definen permisos. Además en nuestro caso hay un servidor LDAP que contiene la base de datos de usuarios que pueden acceder al sistema. La configuración de Samba y de OpenLDAP puede encontrarse en internet en multiples sitios por lo que no voy a detallarla aquí. Voy a hablar de los problemas que hemos tenido y su solución que tiene que ver con el funcionamiento de las redes Windows.
Samba también funciona para compartir unidades de red mediante la red windows así que en muchos sitios se usa como lugar de almacenamiento compartido.
Samba está un poco obsoleto para administrar equipos posteriores a la familia NT, ya que a partir de Windows XP, las políticas de usuario ya no se definien con Poledit sino con las herramientas para "Group Policies" (gpedit.msc, etc). Samba no soporta Group Policies. Así, cuando una máquina con Windows XP tiene definidas políticas de grupo, éstas prevalecen sobre las que envía el servidor Samba y dicho servidor queda inútil en ese sentido.
Existe otro motivo fundamental por el que las políticas definias mediante Samba no tienen efecto en el equipo Windows y es que haya un fichero NTUser.DAT o algun otro NTUSERalgo. Este fichero es generado por Windows y contiene políticas y claves del registro de Windows.
Puede ser que la maquina Windows cliente genere este fichero y lo aloje en el directorio profile de Samba en el servidor. Para evitarlo hay que crear un fichero ntuser.man o poner permisos de sólo lectura en el directorio profile. Tambien puede ser que la maquina Windows no pueda conectar con
el servidor y genere el NTUser.DAT localmente dentro de la carpeta del usuario en C:\Documents and Settings. En tal caso hay que entrar como administrador local y eliminar toda la carpeta. Puede ser que haya que reinciar la máquina para que sea posible borrar.
De lo anterior deduzco que cuando una máquina Windows entra en un dominio, obtiene una copia local de ciertos datos del servidor, ya que permite a los usuarios hacer login incluso sin conexión con el servidor. Por este motivo, si la maquina que ejerce como controlador de dominio cambia, pero el nombre del dominio no ha cambiado, hay que sacar del dominio a los clientes, pasarlos a un
grupo de trabajo y volverlos a meter en el dominio para que funcionen correctamente. Digamos que es la manera de refrescarles los datos que mantienen del servidor. La misma operacion es necesaria para cambiar el nombre de un equipo.

El fichero donde se definen las políticas de usuario se genera con la herramienta Poledit en un pc Windows, y se guarda con el nombre NTconfig.POL en la carpeta netlogon del servidor Samba.
El problema de que el teclado aparezca en inglés se resuelve añadiendo la plantilla administrativa del teclado a Poledit. Esta es la plantilla para que el teclado aparezca en español (keyboard.adm):

CLASS USER

CATEGORY "Keyboard Layout"

POLICY "Poner el teclado en español"
KEYNAME "Keyboard Layout\Preload"
VALUENAME       "1"
VALUEON "0000040a"
VALUEOFF "0000040a"
ACTIONLISTON
VALUENAME       "2"     VALUE   "0000040a"
END ACTIONLISTON
ACTIONLISTOFF
VALUENAME       "2"     VALUE   "0000040a"
END ACTIONLISTOFF
END POLICY

END CATEGORY

Para que la impresora predeterminada aparezca a los usuarios cuando hacen login en la maquina cliente, hemos instalado un script .bat también en el directorio netlogon que contiene lo siguiente:

rundll32 printui.dll,PrintUIEntry /dn /n "\\nombreDelPCqueTieneLaImpresora\HP LaserJet 1200 Series PCL" /q
rundll32 printui.dll,PrintUIEntry /in /n "\\nombreDelPCqueTieneLaImpresora\HP LaserJet 1200 Series PCL"
rundll32 printui.dll,PrintUIEntry /y /n "\\nombreDelPCqueTieneLaImpresora\HP LaserJet 1200 Series PCL"

(Cambie HP LaserJet 1200... por el nombre de su impresora)

He we are writing in this brand new blog category called Plumbing. Welcome to the misterious world of the systems/servers/networking :-S
I started working as a sysadmin some years ago. It is something I don't love exactly but here in the Canaries you have to do everything yourself; you design, you develop, you patch, and you manage the servers and networks. Now I am a Plumbing Power Ranger again! :-) It is nice sometimes though.

The idea of having a Virtual Private Network to which connect a Virtual Machine that is using your local machine resources but accesing the internet through the other peer of the VPN is very useful. This is another idea of my friend Alberto Morales, a.k.a Master Alberto ;-) . By doing so you can see how the network is behaving on the other side of the tunnel so that you get an idea on how the PCs in the office are working. If the system installed in those PCs is the same that you are running in your virtual machine, the conditions are pretty much the same.

This time we are using OpenVPN and VirtualBox which allow us testing Windows or Linux machines as both tools run on Windows and Linux. However we are using Linux right now. OpenVPN uses a static key in the server side for simplicity sake.

Server side, OpenVPN config:

  • /etc/openvpn/server.conf
    proto tcp-server
    dev tap
    up ./server.up
    secret secret.key
  • /etc/openvpn/server.up
    /sbin/ifconfig $1 0.0.0.0 promisc up
    /usr/sbin/brctl addif br0 $1

In order for that to work a bridge br0 has to be configured and up. An ethernet bridge is like a networking switch. When openvpn starts the network interface /dev/tapX (X will be a number) is configured. A tap interface is like the rj45 socket of the switch (ethernet bridge).

What we do to connect the server above using VirtualBox (the client):

  • brctl addbr br1 # create a bridge called bridge 1
  • openvpn --dev tap --remote serverIPorName 1194 --proto tcp-client --secret /etc/openvpn/secret.key
  • # The previous line will create a /dev/tapX device, let's call it /dev/tap2
  • ifconfig tap1 0.0.0.0 promisc up # create tap1 making sure it didn't exist already
  • ifconfig tap2 0.0.0.0 promisc up # set tap2 promisc, considering that tap2 was created by openvpn
  • ifconfig br1 0.0.0.0 promisc up # let the bridge be promisc
  • brctl addif br1 tap1 # give the bridge a socket
  • brctl addif br1 tap2 # give the bridge another socket
  • chmod 0666 /dev/net/tun # set the permissions for the user to access the tap sockets
  • Start virtualbox, select the virtual machine to run, go to settings and configure the network: Use "Host Interface" for the network adapter. Interface name will be tap1, the one that is in the bridge but not used by OpenVPN.

The reason we need 2 tap interfaces is that OpenVPN uses one so it gets busy and the virtual machine needs another. If we just wanted to establish a tunnel with OpenVPN and access the other peer of the virtual LAN, we don't need the bridge in the client side. Just launch OpenVPN with the command above and give an ip address to the tap device:

  • ifconfig tap2 192.168.3.34 netmask 255.255.255.0

Now you should be able to ping the LAN ip of the server. You are in the virtual LAN. If rather than setting the ip manually you request dhcp, the dhcp server will change the default gateway in your local machine so you loose the internet connection and openvpn falls down. Always check the routing table (route -n)
In case you make the same mistake I did and set the ip of the tap device having a bridge with 2 tap devices, you get to weird situations. In that case the packages were sent through tap2 but they were trying to come back through tap1. It ends up in lost packages, tap1 drops packages because it didn't send them. That is: having the bridge with more than one tap device, never give an ip address to any of the tap devices.