C++ 正在等待Qt中的DBus服务可用
在QDbusAbstractInterface(通过qdbusxml2cpp)上构建Qt DBus代理的情况下,什么是处理您想要接口的服务/对象在启动时不可用的最佳方法?注意:我不想简单地了解它(您可以使用BlahService.isValid()来了解它);我想知道它是否有效,知道它何时变为有效,这样我就可以改变状态(并用信号广播状态的改变),然后在状态改变时做其他事情。相反,我想知道,出于类似的原因,它何时不再有效 在不跟踪服务状态的情况下:C++ 正在等待Qt中的DBus服务可用,c++,linux,qt,qt4,dbus,C++,Linux,Qt,Qt4,Dbus,在QDbusAbstractInterface(通过qdbusxml2cpp)上构建Qt DBus代理的情况下,什么是处理您想要接口的服务/对象在启动时不可用的最佳方法?注意:我不想简单地了解它(您可以使用BlahService.isValid()来了解它);我想知道它是否有效,知道它何时变为有效,这样我就可以改变状态(并用信号广播状态的改变),然后在状态改变时做其他事情。相反,我想知道,出于类似的原因,它何时不再有效 在不跟踪服务状态的情况下: #define CONNECT_DBUS_SIG
#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?
}
可能我们需要注意DBus连接对象上的NameOwnerChanged(除非QT的DBus代码为我们这样做),然后当我们获得信号更改状态时,如果需要,连接或断开对象上的信号
我发现的所有示例要么忽略这个问题,要么在服务器对象不存在的情况下直接退出,并且不处理它。Car/Controller Qt示例至少会注意到,如果isValid()在使用过程中变为false,服务器是否会离开并打印“Disconnected”,但它会轮询isValid()
增加:
请注意,QTDBUSABTRACTERFACE注册服务器所有权的更改(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(常量QString和名称,
const QString和oldOwner,
const QString和newOwner)
{
Q_未使用(旧所有者);
if(name==“com.foo.bar.FooService”)
{
qLog(无论什么)在Qt5.3中,serviceOwnerChanged
已被弃用。使用它可以监视特定的服务而不是所有服务。我使用这行代码只获取我想要的服务的信号:QDBusConnection::systemBus().connect(“org.freedesktop.DBus”,“/org/freedesktop/DBus”,“org.freedesktop.DBus”,“名称所有者变更”,QStringList()
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();
}
}
}