Network Manager y DBUS
Anoche publiqué la versión 0.2 de Oraje Applet, con varias novedades (como ¡un icono propio! :D) y algunas correcciones importantes.
Una de las novedades es el soporte de NetworkManager (o NM) vía DBUS, que así en frío no es explicar demasiado :P.
Parece que, por algún motivo (al menos en Fedora 12), las peticiones de resolución de nombres se cachean, lo cual es positivo porque aumenta mucho el rendimiento (si queremos conectar a www.google.com varias veces seguidas, podemos recordar la dirección IP entre llamadas y no tener que hacer la resolución cada vez), pero no es tan bueno si también se cachean los errores :(.
Entonces me encontré con que si el applet se cargaba antes de que tuviéramos conexión a Internet (que en un escritorio se encarga de gestionar NetworkManager, y no tiene porqué cargar antes que Oraje Applet), la resolución del nombre del servicio web de Yahoo! fallaba (claro, si no tenemos conexión, no hay DNS); pero después de que NM hiciera su trabajo y tuviéramos conexión... ¡seguía dando el mismo error!
Por muchas vueltas que le he dado, no he visto cómo cambiar este comportamiento. A nivel de librerías de Python no he encontrado nungún caché relacionado con el DNS (de urllib2 a httplib, y de ahí a socket), así que sospecho que puede ser a nivel de resolver del sistema.
En cualquier caso, el applet debería ser capaz de saber si hay conectividad o no en lugar de forzar un error, y ahí es donde entra DBUS, que es un sistema de mensajes para comunicarnos con otras aplicaciones, y nos va a servir para interactuar con NM, que gestiona la conectividad de red.
Por ejemplo, si queremos saber el estado actual, podemos usar el siguiente código en Python:
import dbus # SystemBus para acceder a NM bus = dbus.SystemBus() proxy = bus.get_object('org.freedesktop.NetworkManager', '/org/freedesktop/NetworkManager') state = proxy.Get('org.freedesktop.NetworkManager', 'state', dbus_interface='org.freedesktop.DBus.Properties') # para traducir a cadenas los valores (0 a 4) trans = [ 'desconocido', 'dormido, interfaces inactivas', 'conectando...', 'conectado', 'desconectado'] print 'El estado de NM es %d (%s)' % (state, trans[state])
De esta manera podemos saber de una forma sencilla el estado de la conectividad cuando arranca nuestra aplicación, obteniendo acceso al bus del sistema (que es donde está NM), y ahí el proxy através del cual haremos las consultas.
Pero, ¿qué ocurre cuando hay un cambio de estado durante la ejecución de nuestra aplicación? Podemos indicarle a NM que llame a una de nuestras funciones cuando se dé un determinado evento.
Aquí es donde he tenido algún problema, porque hay que indicarle a DBUS cuál es el bucle de nuestra aplicación, para que pueda introducir la llamada a nuestra función en la cola de mensajes de ese bucle de forma que no tengamos que estar esperando explícitamente a la señal (uh, esto es una explicación algo libre por mi parte :P).
Como mi aplicación es GTK, tenía que utilizar la librería que permite integrar DBUS con GLib, y me ha costado un poco dar con ese detalle.
En el siguiente ejemplo creamos una ventana que nos va mostrando los cambios de estado de NM:
import pygtk import gtk import dbus from dbus.mainloop.glib import DBusGMainLoop def on_state_changed(state): trans = [ 'desconocido', 'dormido, interfaces inactivas', 'conectando...', 'conectado', 'desconectado'] # cambiamos el texto al nuevo estado label.set_text(trans[state]) # vamos a decirle a DBUS que use el bucle de GLib DBusGMainLoop(set_as_default = True) # NM esta en el SystemBus bus = dbus.SystemBus() proxy = bus.get_object('org.freedesktop.NetworkManager', '/org/freedesktop/NetworkManager') # vamos a preparar una ventana app = gtk.Window(gtk.WINDOW_TOPLEVEL) app.set_title('NM and DBUS fun!') app.connect('destroy', gtk.main_quit) label = gtk.Label('waiting...') box = gtk.HBox() box.add(label) app.add(box) # conectamos StateChanged a nuestra func proxy.connect_to_signal('StateChanged', on_state_changed) app.show_all() gtk.main()
Con lo que ya somos capaces de reaccionar como corresponda ante los cambios de estado de NM ;).
Creo NM es una de las aplicaciones más importantes del escritorio en Linux en los últimos 4 años, sobretodo si trabajamos con portátiles y conexiones inalámbricas o móviles, y gracias a DBUS podemos mejorar mucho la experiencia de usuario en nuestras propias aplicaciones.
Hay más información en la página con la especificación DBUS de NM 0.8, y podemos acceder a DBUS desde diferentes lenguajes de programación.
Hay 2 comentarios
![]()
Sí, es realmente interesante.
Menos mal que DBUS es sencillo de usar, porque el sistema de componentes Bonobo va a ser eliminado de Gnome (se supone que ya no existe en el panel para la reciente 2.32), y hay que pasar a usar un interfaz con DBUS.
Osea, que o migro al nuevo interfaz, o poca utilidad va a tener el applet en poco tiempo :D
Los comentarios están cerrados: los comentarios se cierran automáticamente una vez pasados 15 días. Si quieres comentar algo acerca de la anotación, puedes hacerlo por e-mail.


por r0sk, en 2010-09-27 08:32:58 ∞