Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4263461
  • 博文数量: 776
  • 博客积分: 13014
  • 博客等级: 上将
  • 技术积分: 10391
  • 用 户 组: 普通用户
  • 注册时间: 2010-02-22 17:00
文章分类

全部博文(776)

文章存档

2015年(55)

2014年(43)

2013年(147)

2012年(20)

2011年(82)

2010年(429)

分类: LINUX

2010-03-03 14:22:03

 

总线名字(BUS NAME)
当每个应用程序向总线后台程序(BUS DAEMON)建立连接时,后台程序会立即为这个连接创建一个唯一的连接名(unique connection name).这个唯一的连接名一般都是以冒号:开始,类似:34-907.这个名字在应用程序的生命周期内都是被该应用程序唯一地占用。
应用程序也可以请求更直观的名字(well-known name),例如com.mycompany.TextEditor.应用程序然后就可以向这个总线名字上发送消息。
可以把唯一连接名看作是IP地址(192.168.0.5),而把直观名看作是域名(mycompany.com)。
总线名除了可以路由消息外,而可以用来跟踪连接的生命周期。当应用程序退出后,它的连接将会被操作系统内核关闭。总线后台程序将向其它应用程序发送通知消息,告诉它们这个应用程序的名字已经失去了它的所有者。另外,总线名还可以用来协调单例应用程序,应用程序启动时如果发现它所请求的名字已经占用,就会退出,只允许该应用程序的一个实例存在。

地址(Address)
一个D-Bus服务器程序会在某个地址上侦听,其它的客户端程序连向这个地址。例如unix:path=/tmp/abcdef指定了服务器将在一个UNIX domain socket的路径/tmp/abcdef上侦听消息,客户端将向这个socket上发起连接。
当我们利用消息总线后台程序(message bus daemon)来创建D-Bus应用程序时,libdbus会通过读取系统变量,自动地找出per-session bus daemon的地址。通过检查一个命名好的Unix domain socket路径来发现系统BUS daemon的地址。
当我们不使用消息总线后台程序来创建D-Bus应用程序时,程序员将负责定义哪个是服务器,哪个是客户端,并且提供一种机制来使它们遵守同样的服务器地址。这种情况一般很少见。

概念图(Conceptual Picture)
Address -> [Bus Name] -> Path -> Interface -> Method
方括号内的总线名是可选的,也就是说只有在使用消息后台程序(message bus daemon)时,它才用来将方法调用路由到合适的应用程序。如果是应用程序间的直接连接(不通过daemon),总线名就没有必要了。
其它接口名也是可选的,如果同一个对象路径上没有重名的方法名字的话。

方法调用(Method Call)
总线后台程序不会为消息排序。接收端将会以消息的发送顺序来接收消息,但是接收端并不会保证消息返回时也是按原来顺序返回,例如接收方可能将方法调用处理放在不能的线程里执行,消息返回的顺序依赖了各线程的完成时间。消息调用者使用方法调用(method calls)的一个唯一的序列号来匹配返回消息。

内省(Introspection)
D-Bus对象可以支持一个特定的接口:org.freedesktop.DBus.Introspectable.这个接口有一个方法org.freedesktop.Introspect,这个方法没有参数,返回一个XML字符串。这个XML字符串描述这个对象的接口、方法和信号。

Glib binding示例

int
main (int argc, char **argv)
{
DBusGConnection *connection;
GError *error;
DBusGProxy *proxy;
char **name_list;
char **name_list_ptr;

g_type_init ();

error = NULL;
connection = dbus_g_bus_get (DBUS_BUS_SESSION,
                               &error);
if (connection == NULL)
    {
      g_printerr ("Failed to open connection to bus: %s\n",
                  error->message);
      g_error_free (error);
      exit (1);
    }

/* Create a proxy object for the "bus driver" (name "org.freedesktop.DBus") */

proxy = dbus_g_proxy_new_for_name (connection,
                                     DBUS_SERVICE_DBUS,
                                     DBUS_PATH_DBUS,
                                     DBUS_INTERFACE_DBUS);

/* Call ListNames method, wait for reply */
error = NULL;
if (!dbus_g_proxy_call (proxy, "ListNames", &error, G_TYPE_INVALID,
                          G_TYPE_STRV, &name_list, G_TYPE_INVALID))
    {
      /* Just do demonstrate remote exceptions versus regular GError */
      if (error->domain == DBUS_GERROR && error->code == DBUS_GERROR_REMOTE_EXCEPTION)
        g_printerr ("Caught remote method exception %s: %s",
            dbus_g_error_get_name (error),
            error->message);
      else
        g_printerr ("Error: %s\n", error->message);
      g_error_free (error);
      exit (1);
    }

/* Print the results */

g_print ("Names on the message bus:\n");

for (name_list_ptr = name_list; *name_list_ptr; name_list_ptr++)
    {
      g_print (" %s\n", *name_list_ptr);
    }
g_strfreev (name_list);

g_object_unref (proxy);

return 0;
}

阅读(2147) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~