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 30 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 ∞