等待一个DBus服务在Qt中可用
使用基于QDbusAbstractInterface(通过qdbusxml2cpp)构建的Qt DBus代理,处理想要连接的服务/对象在启动时不可用的最佳方式是什么?注意:我对感兴趣的并不感兴趣(可以使用BlahService.isValid()来查找);我希望能够知道它是否有效,并知道它什么时候变得有效,以便我可以改变状态(并用信号广播状态改变),并且在状态改变时做其他事情。相反,我想知道由于类似原因它何时不再有效。等待一个DBus服务在Qt中可用
没有跟踪服务的状态:
#define CONNECT_DBUS_SIG(x,y) connect(blah,SIGNAL(x),this,SLOT(y))
// FIX - should watch for service, and also handle it going away and
// coming back
blah = new BlahService("com.xyzzy.BlahService", "/com/xyzzy/BlahService",
QDBusConnection::sessionBus(), this);
if (!blah)
return 0;
if (blah.isValid())
{
CONNECT_DBUS_SIG(foo(),Event_foo());
}
else
{
// Since we aren't watching for registration, what can we do but exit?
}
可能是我们需要注意的NameOwnerChanged的的DBus连接对象上 - 除非QT的dbus的代码确实是为我们 - 然后当我们得到信号改变状态,如果需要连接或断开来自物体的信号。
我发现的所有例子都会忽略这个问题,或者只是在服务器对象不存在的情况下退出,并且不会处理它。 Car/Controller Qt示例至少会注意到服务器是否消失并在使用过程中isValid()变为false时打印“Disconnected”,但它是轮询isValid()。
补充:
注意QtDbusAbtractInterface注册服务器(NameOwnerChanged)的所有权的变化和更新的isValid()时可能发生的变化。所以我怀疑你可以直接连接到serverOwnerChanged信号来找出所有权的变化,并将其作为一个指标再次尝试 - 尽管你不能相信isValid,因为它可能会在你得到信号之前或之后被更新。 (丑)你可以设置一个计时器和轮询isValid()。
好了,因为没有人回答,我发现在这期间回答:
你想看NameOwnerChanged:
// subscribe to notifications about when a service is registered/unregistered
connect(QDBusConnection::sessionBus().interface(),
SIGNAL(serviceOwnerChanged(QString,QString,QString)),
this,SLOT(serviceOwnerChanged(QString,QString,QString)));
和
void
VcsApplicationController::serviceOwnerChanged(const QString &name,
const QString &oldOwner,
const QString &newOwner)
{
Q_UNUSED(oldOwner);
if (name == "com.foo.bar.FooService")
{
qLog(Whatever) << "serviceOwnerChanged" << name << oldOwner << newOwner;
if (!newOwner.isEmpty())
{
// New owner in town
emit Initialized();
// or if you control the interface and both sides, you can wait for
// a "Ready()" signal before declaring FooService ready for business.
}
else
{
// indicate we've lost connection, etc
emit Uninitialized();
}
}
}
注意,有可能是在serviceOwnerChanged中使用FooService上的方法进行竞争的条件 - 我不确定它们是否是绑定的副作用(dbus-C++在我的测试用例中),或者dbus设计中固有的(可能的 - 在dbus邮件列表上不会回答这个问题)。如果是是一个真实的竞争条件,那么如果您控制DBus API,则可以等待Ready()/任何信号。如果你不控制另一端,你可以添加一个非常短暂的延迟,或者你也可以看AddMatch()以确保新的所有者也添加了名称上的匹配。
我使用这一行来获取我想要的服务的信号:'QDBusConnection :: systemBus()。connect(“org.freedesktop.DBus”,“/ org/freedesktop/DBus”,“org.freedesktop。 DBus“, ”NameOwnerChanged“, QStringList() Harvey 2012-04-16 00:20:12