مدیریت تماس

در این بخش نحوه پیدا کردن و اضافه کردن یک تماس از DHT به مشتری ارائه می شود. استفاده از یک سرور نام در اینجا توضیح داده نخواهد شد. اگر می خواهید جزئیات بیشتری در مورد آن داشته باشید، لطفاً نام پروتکل سرور را بخوانید.

حضور در شبکه

حضور رو در DHT اعلام کن

حضور آن در DHT اعلام بسیار ساده است. در واقع، این فقط یک مقدار حاوی هشت دستگاه (به بخش قبلی، حساب مدیریت) در هشت مربوط به اثر انگشت کلید است. بنابراین، اگر ما حساب bf5f1e21d3eb2c1246946aa49d5dcf3e5b9cb1b9 با دستگاه 62fbdff0ce86f368c7d3c2682539e5ba9e06404f، مقدار تعریف شده زیر به DHT ارسال می شود:

/**
 * Device announcement stored on DHT.
 */
struct DeviceAnnouncement : public dht::SignedValue<DeviceAnnouncement>
{
private:
    using BaseClass = dht::SignedValue<DeviceAnnouncement>;

public:
    static const constexpr dht::ValueType& TYPE = dht::ValueType::USER_DATA;
    dht::InfoHash dev;
    std::shared_ptr<dht::crypto::PublicKey> pk;
    MSGPACK_DEFINE_MAP(dev, pk)
};

(این مقدار را می توان با `dht_put(h، VALUE، dht::DoneCallback{}، {}، true) ، به عنوان یک قرار دائمی قرار داد. اگر دستگاه اعلام شود، دستگاه موجود است. در حال حاضر، هیچ راهی برای حذف یا ویرایش یک مقدار در DHT وجود ندارد (این زمانی اتفاق می افتد که OpenDHT پشتیبانی از ECC خواهد کرد). بنابراین، حضور همیشه برای حال حاضر تاخیر دارد (متوسط تاخیر: زمان انقضا / 2، بنابراین 2min30 برای حال حاضر).

اگه يه تماس وجود داشته باشه تماس بگير

حالا حضور ما در شبکه، زمان آن است که به دست آوریم که آیا کسی در DHT حضور دارد. با بخش قبلی، فرآیند معکوس را انجام دادن آسان است. برای دانستن اینکه آیا کسی در DHT حضور دارد (مثلا: bf5f1e21d3eb2c1246946aa49d5dcf3e5b9c1b9) ، ما باید ارزش را در bf5f1e21d3eb2c1246946aa49d5dcf3e5b9cb1b9 پیدا کنیم و DeviceAnnouncement را در این هش بازیافت کنیم. کد مرتبط در دایمونی در ccount.cpp:

auto shared = std::static_pointer_cast<RingAccount>(shared_from_this());
auto treatedDevices = std::make_shared<std::set<dht::InfoHash>>();
dht_.get<dht::crypto::RevocationList>(to, [to](dht::crypto::RevocationList&& crl){
    tls::CertificateStore::instance().pinRevocationList(to.toString(), std::move(crl));
    return true;
});
dht_.get<DeviceAnnouncement>(to, [shared,to,treatedDevices,op](DeviceAnnouncement&& dev) {
    if (dev.from != to)
        return true;
    if (treatedDevices->emplace(dev.dev).second)
        op(shared, dev.dev);
    return true;
}, [=](bool /*ok*/){
    {
        std::lock_guard<std::recursive_mutex> lock(shared->buddyInfoMtx);
        auto buddy_info_it = shared->trackedBuddies_.find(to);
        if (buddy_info_it != shared->trackedBuddies_.end()) {
            if (not treatedDevices->empty()) {
                for (auto& device_id : *treatedDevices)
                    shared->onTrackedBuddyOnline(buddy_info_it, device_id);
            } else
                shared->onTrackedBuddyOffline(buddy_info_it);
        }
    }
    RING_DBG("[Account %s] found %lu devices for %s",
                getAccountID().c_str(), treatedDevices->size(), to.to_c_str());
    if (end) end(shared, not treatedDevices->empty());
});

و اين همه چيزه

Client perspective

<method name="subscribeBuddy" tp:name-for-bindings="subscribeBuddy">
    <tp:docstring>
        Ask be be notified when 'uri' presence change
    </tp:docstring>
    <tp:added version="1.3.0"/>
    <arg type="s" name="accountID" direction="in">
        <tp:docstring>
            An account from which get request presence informations
        </tp:docstring>
    </arg>
    <arg type="s" name="uri" direction="in">
        <tp:docstring>
            A SIP uri to watch
        </tp:docstring>
    </arg>
    <arg type="b" name="flag" direction="in">
        <tp:docstring>
        </tp:docstring>
    </arg>
</method>

<signal name="newBuddyNotification" tp:name-for-bindings="newBuddyNotification">
    <tp:added version="1.3.0"/>
    <tp:docstring>
        Notify when a registered presence uri presence informations changes
    </tp:docstring>
    <arg type="s" name="accountID">
        <tp:docstring>
            The associated account
        </tp:docstring>
    </arg>
    <arg type="s" name="buddyUri">
        <tp:docstring>
            The registered URI
        </tp:docstring>
    </arg>
    <arg type="i" name="status">
        <tp:docstring>
            Is the URI present or not
        </tp:docstring>
    </arg>
    <arg type="s" name="lineStatus">
        <tp:docstring>
            A string containing informations from the user (human readable)
        </tp:docstring>
    </arg>
</signal>

<method name="publish" tp:name-for-bindings="publish">
    <tp:added version="1.3.0"/>
    <arg type="s" name="accountID" direction="in">
        <tp:docstring>
            The account from which the presence will be emitted
        </tp:docstring>
    </arg>
    <arg type="b" name="status" direction="in">
        <tp:docstring>
            Is this account present or not
        </tp:docstring>
    </arg>
    <arg type="s" name="note" direction="in">
        <tp:docstring>
            A message transmitted by the server to other users
        </tp:docstring>
    </arg>
</method>

Are the main APIs for clients. subscribeBuddy will listen on the DHT to detect presence changes and newBuddyNotification will be sent whenever a new status is detected:

  • The status sent to the client is now 0=offline (no device found on the DHT), 1=dht_presence (at least a device is found on the DHT), 2=connected (with a TCP + SIP channel, so ready to exchange data).

  • lineStatus will contain any custom status sent by the peer (e.g. Lunch Time!)

publish is used for publishing a custom note (status is ignored for Jami accounts, note will contain the custom status).

RFC3863 is used to send status over the SIP connection.

درخواست منتظر

درخواست بفرستید

** درخواست کشتی های TODO**

در نهایت، هنگامی که درخواست اعتماد صورت گرفته است، می توانیم درخواست را به هش زیر فشار دهیم: InfoHash("inbox:" + deviceId)

کد زیر در دایمون استفاده می شود:

dht_.putEncrypted(dht::InfoHash::get("inbox:"+dev.toString()), dev, dht::TrustRequest(DHT_TYPE_NS, payload));

دریافت درخواست

TODO

(قبول/بلاک/فروخت)

API دیمون

تمام روش های پیگیری حضور یک دوست در `PresenceManager]] قرار دارد مانند:

<signal name="newBuddyNotification" tp:name-for-bindings="newBuddyNotification">
    <tp:added version="1.3.0"/>
    <tp:docstring>
        Notify when a registered presence uri presence informations changes
    </tp:docstring>
    <arg type="s" name="accountID">
        <tp:docstring>
            The associated account
        </tp:docstring>
    </arg>
    <arg type="s" name="buddyUri">
        <tp:docstring>
            The registered URI
        </tp:docstring>
    </arg>
    <arg type="b" name="status">
        <tp:docstring>
            Is the URI present or not
        </tp:docstring>
    </arg>
    <arg type="s" name="lineStatus">
        <tp:docstring>
            A string containing informations from the user (human readable)
        </tp:docstring>
    </arg>
</signal>

تمام روش ها و سیگنال هایی که برای مدیریت درخواست ها و تماس های اعتماد استفاده می شود در `ConfigurationManager]] قرار دارند مانند:

<method name="getTrustRequests" tp:name-for-bindings="getTrustRequests">
    <tp:added version="2.2.0"/>
    <arg type="s" name="accountID" direction="in">
    </arg>
    <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="VectorMapStringString"/>
    <arg type="aa{ss}" name="requests" direction="out" >
        <tp:docstring>
            A list of contact request details. Details:
            - from: account ID of sender
            - received: UNIX timestamp of reception date
            - payload: attached payload
        </tp:docstring>
    </arg>
</method>

<method name="acceptTrustRequest" tp:name-for-bindings="acceptTrustRequest">
    <tp:added version="2.2.0"/>
    <arg type="s" name="accountID" direction="in">
    </arg>
    <arg type="s" name="from" direction="in">
    </arg>
    <arg type="b" name="success" direction="out" tp:type="Boolean">
        <tp:docstring>
            True if the operation succeeded.
        </tp:docstring>
    </arg>
</method>

<method name="discardTrustRequest" tp:name-for-bindings="discardTrustRequest">
    <tp:added version="2.2.0"/>
    <arg type="s" name="accountID" direction="in">
    </arg>
    <arg type="s" name="from" direction="in">
    </arg>
    <arg type="b" name="success" direction="out" tp:type="Boolean">
        <tp:docstring>
            True if the operation succeeded.
        </tp:docstring>
    </arg>
</method>

<signal name="incomingTrustRequest" tp:name-for-bindings="incomingTrustRequest">
    <tp:added version="2.2.0"/>
    <tp:docstring>
        Notify clients that a new contact request has been received.
    </tp:docstring>
    <arg type="s" name="accountID">
    </arg>
    <arg type="s" name="from">
    </arg>
    <arg type="ay" name="payload">
    </arg>
    <arg type="t" name="receiveTime">
    </arg>
</signal>

<method name="sendTrustRequest" tp:name-for-bindings="sendTrustRequest">
    <tp:added version="2.2.0"/>
    <arg type="s" name="accountID" direction="in">
    </arg>
    <arg type="s" name="to" direction="in">
    </arg>
    <arg type="ay" name="payload" direction="in">
    </arg>
</method>

<method name="addContact" tp:name-for-bindings="addContact">
    <tp:added version="3.0.0"/>
    <arg type="s" name="accountID" direction="in">
    </arg>
    <arg type="s" name="uri" direction="in">
    </arg>
</method>

<method name="removeContact" tp:name-for-bindings="removeContact">
    <tp:added version="3.0.0"/>
    <arg type="s" name="accountID" direction="in">
    </arg>
    <arg type="s" name="uri" direction="in">
    </arg>
    <arg type="b" name="ban" direction="in" tp:type="Boolean">
        <tp:docstring>
            True if the the contact should be banned.
            If false, the contact is removed from the contact list (banned or not).
        </tp:docstring>
    </arg>
</method>

اگر می خواهید چند مثال، این روش ها در contactmodel.cpp در LRC استفاده می شوند.