2009-09-14 4 views
11

QDbusAbstractInterface (qdbusxml2cpp를 통해)에 빌드 된 Qt DBus 프록시를 사용하면 시작할 때 사용할 인터페이스가없는 서비스/오브젝트를 처리하는 가장 좋은 방법은 무엇입니까? 참고 : 간단히 알면 관심이 없습니다 (BlahService.isValid()를 사용하여 찾을 수 있음). 나는 그것이 유효한지를 알 수 있기를 원하고 언제 그것이 유효하게되었는지를 알기 때문에 상태를 바꿀 수 있고 (신호로 상태 변화를 방송 할 수있다), 그 상태 변화에 다른 일을 할 수있다. 반대로, 비슷한 이유로 더 이상 유효하지 않은시기를 알고 싶습니다. 서비스의 상태를 추적하지 않고Qt에서 DBus 서비스를 기다리는 중

:

#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()는 폴링합니다.

추가 : QtDbusAbtractInterface 서버 (NameOwnerChanged)의 소유권의 변경 및 업데이트 isValid() 변경이 발생할를 등록

참고. 따라서 serverOwnerChanged 신호에 직접 연결하여 소유권 변경 사항을 직접 확인하고 다시 시도 할 지표로 사용할 수 있다고 생각합니다. 시그널링되기 전이나 후에 업데이트 될 수 있기 때문에 isValid를 신뢰하지 못할 수도 있습니다.

또는 (못생긴) 타이머를 설정하고 isValid()를 폴링 할 수 있습니다.

답변

9

이 좋아, 아무도 대답하지 않기 때문에, 나는 그 사이에서 답을 발견했습니다 :

당신은 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()를보고 새 소유자가 이름에도 일치 항목을 추가했는지 확인할 수 있습니다.

+0

필자는이 줄을 사용하여 원하는 서비스에 대한 신호만을 얻습니다. QDBusConnection :: systemBus(). connect ("org.freedesktop.DBus", "/ org/freedesktop/DBus", "org.freedesktop. (QString, QString, QString)); '경쟁 조건에 관해서는, 나는 (DBString), "NameOwnerChanged", QStringList() ""org.freedesktop.Avahi ","sss ", SLOT (AvahiNameOwnerChanged 이 신호를 받으면 내 이전 인터페이스를 삭제하고 새 인터페이스를 얻으십시오. – Harvey

3

Qt 5.3의 경우 serviceOwnerChanged은 더 이상 사용되지 않습니다. QDBusServiceWatcher을 사용하면 모든 서비스 대신 특정 서비스를 볼 수 있습니다.

관련 문제