2009-09-14 13 views
11

में एक डीबीस सेवा उपलब्ध होने की प्रतीक्षा कर रहा है QDbusAbstractInterface (qdbusxml2cpp के माध्यम से) पर निर्मित एक क्यूटी डीबीस प्रॉक्सी के साथ, सेवा शुरू करने के लिए आप जिस इंटरफ़ेस को इंटरफ़ेस करना चाहते हैं उसे संभालने का सबसे अच्छा तरीका क्या है? नोट: मुझे बस इसे जानने में दिलचस्पी नहीं है (आप इसे खोजने के लिए BlahService.isValid() का उपयोग कर सकते हैं); मैं अगर यह वैध है पता है, और पता है जब यह मान्य हो जाता है तो मैं राज्य को बदल सकते हैं (और एक संकेत के साथ कि राज्य परिवर्तन प्रसारण) करने में सक्षम होना चाहता हूँ, और कहा कि राज्य परिवर्तन पर अन्य सामान है। इसके विपरीत, मैं जानना चाहता हूं कि यह समान कारणों से कब वैध नहीं है।क्यूटी

सेवा के राज्य पर नज़र रखने के बिना

:

#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 के लिए देखने की जरूरत है - हमारे लिए जब तक क्यूटी के dbus कोड करता है - और फिर जब हम उस संकेत परिवर्तन राज्य मिल , और यदि आवश्यक हो तो ऑब्जेक्ट से संकेतों को कनेक्ट या डिस्कनेक्ट करें।

सभी उदाहरण मुझे लगता है, या तो जारी या बस से बाहर निकलने की उपेक्षा करता है, तो सर्वर ऑब्जेक्ट मौजूद नहीं है, और इसे दूर जा रहा से निपटने के नहीं है। कम से कम नोटिस पर कार/नियंत्रक क्यूटी उदाहरण यदि सर्वर दूर चला जाता है और प्रिंट "डिस्कनेक्टेड" अगर अगर है() उपयोग के दौरान झूठी हो जाता है, लेकिन यह मतदान अगर है() है।

जोड़ा गया:

ध्यान दें कि QtDbusAbtractInterface सर्वर (NameOwnerChanged) के स्वामित्व के परिवर्तन और अद्यतन अगर है() जब परिवर्तन होते हैं के लिए पंजीकृत करता है। तो मुझे लगता है कि आप सीधे स्वामित्व में परिवर्तन के बारे में पता है और कहा कि एक संकेतक के रूप में पुन: प्रयास करने के लिए उपयोग करने के लिए है कि serverOwnerChanged सिग्नल से कनेक्ट कर सकते हैं - हालांकि आप अगर है पर भरोसा करने में सक्षम है, क्योंकि यह पहले या आप संकेत मिलता है के बाद अद्यतन किया जा सकता नहीं होगा।

वैकल्पिक रूप से (बदसूरत) आप अगर है के लिए एक टाइमर और मतदान सेट कर सकते हैं()।

उत्तर

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(); 
     } 
    } 
} 

ध्यान दें कि वहाँ सेवा के भीतर से FooService पर विधियों के साथ दौड़ की स्थिति हो सकती हैऑनर चेंज - मुझे अभी तक यकीन नहीं है कि वे बाध्यकारी का दुष्प्रभाव हैं (dbus-C++ अपने परीक्षण के मामले में), या dbus (संभव के डिजाइन में निहित है - कोई पर dbus मेलिंग सूची सवाल का जवाब होगा) पर। यदि वास्तविक दौड़ की स्थिति है, तो आप डीबीस एपीआई को नियंत्रित करते समय तैयार()/जो भी सिग्नल पर प्रतीक्षा कर सकते हैं। यदि आप दूसरे छोर को नियंत्रित नहीं करते हैं, तो आप बहुत कम देरी जोड़ सकते हैं या आप यह सुनिश्चित करने के लिए AddMatch() भी देख सकते हैं कि नए मालिक ने नाम पर एक मैच भी जोड़ा है।

+0

मैं इस लाइन का उपयोग केवल उस सेवा के लिए सिग्नल प्राप्त करने के लिए करता हूं जो मैं चाहता हूं: 'QDBusConnection :: systemBus()। कनेक्ट करें ("org.freedesktop.DBus", "/ org/freedesktop/DBus", "org.freedesktop। डीबीस ", " NameOwnerChanged ", क्यूस्ट्रिंगलिस्ट() <<" org.freedesktop.Avahi "," sss ", यह, एसएलओटी (AvahiNameOwnerChanged (QString, QString, QString)); 'दौड़ की स्थिति के रूप में, मैं एक बार मुझे यह संकेत मिलने के बाद मेरा पुराना इंटरफ़ेस हटाएं और एक नया प्राप्त करें। – Harvey

3

क्यूटी 5.3, serviceOwnerChanged के साथ बहिष्कृत किया गया है। QDBusServiceWatcher का उपयोग करें जो सभी की बजाय किसी विशिष्ट सेवा को देखने की अनुमति देता है।