Con un proxy Qt DBus basato su QDbusAbstractInterface (tramite qdbusxml2cpp), qual è il modo migliore di gestire il servizio/oggetto che si desidera interfacciare per non essere disponibile quando si avvia? Nota: non mi interessa semplicemente conoscerlo (puoi usare BlahService.isValid() per scoprirlo); Voglio essere in grado di sapere se è valido, e sapere quando diventa valido, così posso cambiare stato (e trasmettere quel cambiamento di stato con un segnale), e su quel cambiamento di stato fare altre cose. Al contrario, voglio sapere quando non è più valido per ragioni simili.In attesa che un servizio DBus sia disponibile in Qt
Senza il monitoraggio dello stato del servizio:
#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?
}
Probabilmente abbiamo bisogno di guardare per NameOwnerChanged sull'oggetto di connessione DBus - a meno che il codice dbus del QT fa questo per noi - e poi quando otteniamo quello stato cambio di segnale e, se necessario, collegare o disconnettere i segnali dall'oggetto.
Tutti gli esempi che trovo o ignorano il problema o semplicemente escono se l'oggetto server non esiste e non si occupano di andare via. L'esempio Qt Car/Controller rileva almeno se il server si spegne e stampa "Disconnected" se isValid() diventa falso durante l'uso, ma è polling isValid().
Aggiunto:
noti che QtDbusAbtractInterface registra per passaggi di proprietà del server (NameOwnerChanged), e aggiornamenti IsValid() in caso di cambiamenti. Quindi sospetto che tu possa connettersi direttamente al segnale serverOwnerChanged per scoprire le modifiche alla proprietà e usarlo come indicatore per riprovare, anche se non sarai in grado di fidarti diValido perché potrebbe essere aggiornato prima o dopo aver ricevuto il segnale.
In alternativa (brutto) è possibile impostare un timer e il polling per isValid().
Io uso questa linea per ottenere solo il segnale per il servizio che desidero: 'QDBusConnection :: systemBus(). Connect (" org.freedesktop.DBus ","/org/freedesktop/DBus "," org.freedesktop. DBus ", " NameOwnerChanged ", QStringList() <<" org.freedesktop.Avahi "," sss ", this, SLOT (AvahiNameOwnerChanged (QString, QString, QString)))' Per quanto riguarda le condizioni di gara, I cancella la mia vecchia interfaccia e ne ottieni una nuova quando ottengo questo segnale. – Harvey