연락처 관리
이 섹션에서는 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).
연락처가 있는 경우 연락
Now our presence on the network, it’s time to get if somebody is present on the DHT. With the previous section, it’s easy to do the reverse process. To know if somebody is present on the DHT (ex: bf5f1e21d3eb2c1246946aa49d5dcf3e5b9cb1b9
), we have to get value at bf5f1e21d3eb2c1246946aa49d5dcf3e5b9cb1b9
and retrieve the DeviceAnnouncement
on this hash. The related code in the daemon is in jamiaccount.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.
상정 요청
요청 보내
TDO 배신 요청
마지막으로, 신뢰 요청이 작성되면 다음 해시로 요청을 밀어 넣을 수 있습니다: InfoHash("inbox:" + deviceId)
이 데이몬에는 다음과 같은 코드 사용된다.
dht_.putEncrypted(dht::InfoHash::get("inbox:"+dev.toString()), dev, dht::TrustRequest(DHT_TYPE_NS, payload));
요청 받은 것
TDO
(수용/ 차단/ 폐기)
대몬 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>
몇 가지 예제를 원한다면, 이 방법들은 LRC에서 kontakmodel.cpp
에 사용된다.