联系管理
本节将介绍如何从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上的值 (这将在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船只要求
最后,当信任请求完成后,我们可以将请求推到以下哈希:
在 daemon 中使用以下代码:
dht_.putEncrypted(dht::InfoHash::get("inbox:"+dev.toString()), dev, dht::TrustRequest(DHT_TYPE_NS, payload));
收到请求
鱼类
(接受/封锁/拒绝)
鱼的API
△ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △ △
<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>
所有用于管理信任请求和联系的方法和信号都在”配置管理员”中,如:
<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中使用在 contactmodel.cpp
.