群れ

A swarm (group chat) is a set of participants capable of resilient, decentralized communication. For example, if two participants lose connectivity with the rest of the group (e.g., during an Internet outage) but can still reach each other over a LAN or subnetwork, they can exchange messages locally and then synchronize with the rest of the group once connectivity is restored.

A swarm is defined by the following properties:

  1. Ability to split and merge based on network connectivity.

  2. History synchronization. Every participant must be able to send a message to the entire group.

  3. サーバーに頼るわけにはいかない

  4. Non-repudiation. Devices must be able to verify past messages' validity and to replay the entire history.

  5. Perfect Forward Secrecy (PFS) is provided on the transport channels. Storage is handled by each device.

メインアイデアは 参加者とのマークルツリーを同期することです

We identified four modes for swarms that we want to implement:

  • ONE_TO_ONE: A private conversation between two endpoints—either between two users or with yourself.

  • ADMIN_INVITES_ONLY: A swarm in which only the administrator can invite members (for example, a teacher-managed classroom).

  • INVITES_ONLY: A closed swarm that admits members strictly by invitation; no one may join without explicit approval.

  • PUBLIC: A public swarm that anyone can join without prior invitation (For example a forum).

シナリオ

群れを作れ

ボブは新しい群れを作りたい

  1. Bob creates a local Git repository.

  2. その後,彼は次の署名による最初のコミットメントを作成します

    • /admins の公钥

    • 装置証明書 ̀ /デバイス`

    • /crls` のCRL

  3. 最初のコンタクトのハッシュは会話のIDになります

  4. Bob announces to his other devices that he created a new conversation. This is done via an invite to join the group sent through the DHT to other devices linked to that account.

誰かを追加する

Bob adds Alice

  1. Bob adds Alice to the repo:

    • /invited で招待された URI を追加する

    • /crls にCRLを追加する

  2. Bob sends a request on the DHT.

招待状 を 受け入れる

Alice gets the invite to join the previously created swarm

  1. Alice accepts the invite (if she declines, nothing happens; she will remain in the "invited" list, and will never receive any messages)

  2. A peer-to-peer connection is established between Alice and Bob.

  3. Alice pulls the Git repository from Bob. WARNING this means that messages require a connection, not from the DHT as it is today.

  4. Alice validates the commits from Bob.

  5. To validate that Alice is a member, she removes the invite from /invited directory, then adds her certificate to the /members directory

  6. Once all commits are validated and syncronized to her device, Alice discovers other members of the group. with these peers, she will then construct the DRT with Bob as a bootstrap.

メッセージを送る

Alice sends a message to Bob

  1. Alice creates a commit message. She constructs a JSON payload containing the MIME type and message body. For example:

{
    "type": "text/plain",
    "body": "hello"
}
  1. Alice ensure her device credentials are present. If Alice’s device certificate or its associated CRL isn’t already stored in the repository, she adds them so that other participants can verify the commit.

  2. Alice commits to the repository (Because Jami relies primarily on commit-message metadata rather than file contents, merge conflicts are rare; the only potential conflicts would involve CRLs or certificates, which are versioned in a dedicated location).

  3. Alice announces the commit via the DRT with a service message and pings the DHT for mobile devices (they must receive a push notification).

注釈

To notify other devices, the sender transmits a SIP message with type: application/im-gitmessage-id. The JSON payload includes the deviceId (the sender’s), the conversationId and the reference (hash) of the new commit.

メッセージを受け取る

Bob receives a message from Alice

  1. Bob performs a Git pull on Alice's repository.

  2. All incoming commits MUST be verified by a hook.

  3. If all commits are valid, commits are stored and displayed.Bob then announces the message via the DRT for other devices.

  4. If any commit is invalid, pull is aborted. Alice must restore her repository to a correct state before retrying.

コミットメントの検証

ユーザが不必要なコンビット (紛争,偽メッセージなど) を押し付けないようにするために,各コンビット (古いから新しいまで) は,リモートブランチを統合する前に,このように検証する必要があります.

注釈

  1. If the validation fails, the fetch is ignored and we do not merge the branch (and remove the data), and the user should be notified.

  2. If a fetch is too big, it's not merged.

  • For each incoming commit, ensure that the sending device is currently authorized and that the issuer’s certificate exists under /members or /admins, and the device’s certificate under /devices.

  • Then handle one of three cases, based on the commit’s parent count:

    • Merge Commit (2 parents). No further validation is required, merges are always accepted.

    • Initial Commit (0 parents). Validate that this is the very first repository snapshot:

      • Admin certificate is added.

      • Device certificate is added.

      • CRLs (Certificate Revocation Lists) are added.

      • No other files are present.

    • Ordinary Commit (1 parent). The commit message must be JSON with a top‑level type field. Handle each type as follows:

      • If text (or any non–file‑modifying MIME type)

        • Signature is valid against the author’s certificate in the repo.

        • No unexpected files are added or removed.

      • If vote

        • voteType is one of the supported values (e.g. "ban", "unban").

        • The vote matches the signing user.

        • The signer is an admin, their device is present, and not themselves banned.

        • No unexpected files are added or removed.

      • If member

        • If adds

          • Properly signed by the inviter.

          • New member’s URI appears under /invited.

          • No unexpected files are added or removed.

          • If ONE_TO_ONE, ensure exactly one admin and one member.

          • If ADMIN_INVITES_ONLY, the inviter must be an admin.

        • If joins

          • Properly signed by the joining device.

          • Device certificate added under /devices.

          • Corresponding invite removed from /invited and certificate added to /members.

          • No unexpected files are added or removed.

        • If banned

          • Vote is valid per the vote rules above.

          • Ban is issued by an admin.

          • Target’s certificate moved to /banned.

          • Only files related to the ban vote are removed.

          • No unexpected files are added or removed.

      • Fallback. If the commit’s type or structure is unrecognized, reject it and notify the peer (or user) that they may be running an outdated version or attempting unauthorized changes.

装置を禁止する

重要

Jami source code tends to use the terms (un)ban, while the user interface uses the terms (un)block.

Alice, Bob, Carla, Denys are in a swarm. Alice issues a ban against Denys.

In a fully peer‑to‑peer system with no central authority, this simple action exposes three core challenges:

  1. Untrusted Timestamps: Commit timestamps cannot be relied upon for ordering ban events, as any device can forge or replay commits with arbitrary dates.

  2. Conflicting bans: In cases where multiple admin devices exist, network partitions can result in conflicting ban decisions. For instance, if Alice can communicate with Bob but not with Denys and Carla, while Carla can communicate with Denys, conflicting bans may occur. If Denys bans Alice while Alice bans Denys, the group’s state becomes unclear when all members eventually reconnect and merge their conversation histories.

  3. Compromised or expired devices: Devices can be compromised, stolen, or have their certificates expire. The system must allow banning such devices and ensure they cannot manipulate their certificate or commit timestamps to send unauthorized messages or falsify their expiration status.

類似したシステム (分散型グループシステム) はあまりないが,以下はいくつかの例です.

  • [mpOTRは誰かを禁止する方法を定義していない]

  • グループチャット用の中央サーバーがないため (EDIT:最近その点を変更しました) グループから誰かを禁止する機能は与えません

This voting system needs a human action to ban someone or must be based on the CRLs info from the repository (because we can not trust external CRLs).

会話からデバイスを削除する

議論の分裂を避けるために 合意が必要とする唯一の部分です 例えば2人のメンバーが会話から 互いを蹴った場合 第三者はどうでしょう

削除されたデバイスを検出するために,または公共の部屋に不必要な人が登場するのを避けるために必要なものです.メンバーとデバイスの間のプロセスはかなり類似しています.

♪アリスがボブを連れ去る ♪

重要

Alice MUST be an admin to vote.

  • 投票はボブを禁止する.そのために,彼女はファイルを /votes/ban/members/uri_bob/uri_alice (メンバーはデバイスのためのデバイスに置き換えることができる,または招待状や管理者への招待状に招待される) で作成し,

  • 投票が決まったかどうかを確認します. これは,管理者の50%以上がボブを禁止することに同意していることを意味します (彼女が一人なら,それは50%以上です).

  • 投票が解決された場合, /votes/ban のファイルは削除され, /members, /admins, /invited, /CRL, /device の Bob のすべてのファイルは削除され (または禁止されたデバイスの場合のみ /device で) そして, Bob の証明書は /banned/members/bob_uri.crt に置き, repo に委託され,

  • その後,アリスは他のユーザーに (ボブ以外)

Alice (admin) re-adds Bob (banned member)

  • If she votes for unbanning Bob. To do that, she creates the file in /votes/unban/members/uri_bob/uri_alice (members can be replaced by devices for a device, or invited for invites or admins for admins) and commits

  • 投票が決まったかどうかを確認します. これは,管理者の50%以上がボブを禁止することに同意していることを意味します (彼女が一人なら,それは50%以上です).

  • 投票が解決された場合, /votes/unban のファイルは削除され, /members, /admins, /invited, /CRL の Bob のすべてのファイルが,再添加され, /device にのみ追加され, repo にコミットされます.

話しを削除する

  1. convInfos remove=time::now() で保存します (削除Contactは連絡先で保存します) 会話が削除され,他のユーザーのデバイスと同期されます

  2. もしこの会話に新しい約束が 受け取られたら 無視される

  3. ジュミがスタートアップして レポがまだ存在しているなら 顧客に会話が発表されない

  4. Two cases: a. If no other member in the conversation we can immediately remove the repository b. If still other members, commit that we leave the conversation, and now wait that at least another device sync this message. This avoids the fact that other members will still detect the user as a valid member and still sends new message notifications.

  5. 確認すると,削除された=time::now() を削除し,他のユーザーのデバイスと同期します

  6. ユーザー所有するすべてのデバイスは,現在,リポジトリと関連ファイルを削除することができます

モードを指定する方法

設定は変更できません.または別の会話です.このデータは最初のコミットメッセージに保存されます.

{
    "type": "initial",
    "mode": 0,
}

現在, "モード" は値 0 (ONE_TO_ONE), 1 (ADMIN_INVITES_ONLY), 2 (INVITES_ONLY), 3 (PUBLIC) を受け入れます

Processes for 1:1 chats

The goal here is to keep the old API (addContact/removeContact, sendTrustRequest/acceptTrustRequest/discardTrustRequest) to create a chat with a peer and its contact. This still implies some changes that we cannot ignore:

プロセスはまだ同じです アカウントは addContact で連絡先を追加し,DHT で TrustRequest を送信できます.しかし,二つの変更が必要になります.

  1. TrustRequest は,要求を受け入れたときにどの会話をクローンするか,同級者に知らせる"会話Id"を組み込みます

  2. TrustRequest は,連絡がオンラインに戻ると再試されます.今日ではそうではありません (同級者が最初の TrustRequest を捨てると新しい TrustRequest を生成したくないので).したがって,アカウントが信頼要求を受け取ると,関連する会話による要求が拒否された場合自動的に無視されます ( convRequests が同期されるので)

連絡先が要求を受け入れたら シンクロレーション期間が必要になります 連絡先が会話をクローンする必要があるからです

連絡先を削除する (Contact) は,連絡先と関連した 1:1 会話 ("会話を削除する"と同じプロセスで) を削除します. ここで唯一注意するのは,連絡先を禁止した場合,同期を待つのではなく,関連するファイルすべて削除するということです.

難しいシナリオ

議論の2つの場面がある場合 少なくとも2つのシナリオです

  1. Alice adds Bob.

  2. Bob accepts.

  3. Alice removes Bob.

  4. Alice adds Bob.

及び

  1. Alice adds Bob and Bob adds Alice at the same time, but both are not connected together.

In this case, two conversations are generated. We don't want to remove messages from users or choose one conversation here. So, sometimes two conversations between the same members will be shown. It will generate some bugs during the transition time (as we don't want to break API, the inferred conversation will be one of the two shown conversations, but for now it's "ok-ish", will be fixed when clients will fully handle conversationId for all APIs (calls, file transfer, etc)).

重要

After accepting a conversation's request, there is a time the daemon needs to retrieve the distant repository. During this time, clients MUST show a syncing view to give informations to the user. While syncing:

  • ConfigurationManager::getConversations() will return the conversation's id even while syncing.

  • ConfigurationManager::conversationInfos() は,同期した場合, {{"同期": "真"}} を返します.

  • ConfigurationManager::getConversationMembers() will return a map of two URIs (the current account and the peer who sent the request).

協議は仕様要求

会話の要求は,次のキーで Map<String,String> で表現されます.

  • id: the conversation ID

  • from: URI of the sender

  • 受け取った: タイムスタンプ

  • タイトル: (オプション) 会話の名前

  • 記述: (オプション)

  • avatar: (optional) the profile picture

会話のプロフィール同期

識別可能になるためには,会話は一般的にタイトル (例えば,Jami) や説明 (例えば,いくつかのリンク,プロジェクトとは何か,など) や画像 (プロジェクトのロゴ) などのようなメタデータが必要です.これらのメタデータはオプションであるが,すべてのメンバーと共有されるため,同期し,要求に組み込む必要があります.

倉庫の保存

会話のプロフィールは, vCardファイルで root (/profile.vcf) に保存されます.

BEGIN:VCARD
VERSION:2.1
FN:TITLE
DESCRIPTION:DESC
END:VCARD

シンクロニズ

To update the vCard, a user with enough permissions (by default: =ADMIN) needs to edit /profile.vcf and will commit the file with the mimetype application/update-profile. The new message is sent via the same mechanism and all peers will receive the MessageReceived signal from the daemon. The branch is dropped if the commit contains other files or too big or if done by a non-authorized member (by default: <ADMIN).

最後に表示

通信の状態は,通信の状態を他のデバイスに送信する.この状態では,最後の表示が送信されます.しかし,各デバイスは,それぞれの会話に対して独自の状態を持つことができるため,おそらく同じ最後のコミットを何らかの時点でせずに,いくつかのシナリオが考慮に入れる:

5つのシナリオがサポートされています.

  • 他のデバイスから送信された最後の表示が現在のものと同じなら,何もできない.

  • 現在のデバイスに最後の表示がない場合,リモート表示されたメッセージが使用されます.

  • 削除されたリモコンがリポに表示されていない場合,commitが後で取得されるので,結果をキャッシュします.

  • 移動したリモコンが既に取れた場合, 移動したリモコンが過去に表示されていることを確認します.

  • 最後に 同じ作者からのメッセージが発表されると, 最後に表示されたメッセージを更新する必要があるということです.

優先順位

ユーザーによって設定された好評がすべての会話に添付されています.これらの好評はユーザーのデバイスに同期されます.これは,ユーザーが通知を無視したい場合,ファイル転送サイズ制限などの場合,会話の色かもしれません.現在,認識されたキーは:

  • "color" - the color of the conversation (#RRGGBB format)

  • "無知通知" - この会話で新しいメッセージの通知を無視する

  • "シンボル" - デフォルトエモジを定義する

accountDir/conversation_data/conversationId/preferencesで保存され,同ユーザーのデバイスにSyncMsg を介してのみ送信されます.

優先順位と相互作用するAPIは:

// Update preferences
void setConversationPreferences(const std::string& accountId,
                                const std::string& conversationId,
                                const std::map<std::string, std::string>& prefs);
// Retrieve preferences
std::map<std::string, std::string> getConversationPreferences(const std::string& accountId,
                                                              const std::string& conversationId);
// Emitted when preferences are updated (via setConversationPreferences or by syncing with other devices)
struct ConversationPreferencesUpdated
{
    constexpr static const char* name = "ConversationPreferencesUpdated";
    using cb_type = void(const std::string& /*accountId*/,
                            const std::string& /*conversationId*/,
                            std::map<std::string, std::string> /*preferences*/);
};

合併紛争管理

profile.vcfでは2つの管理者が同時に記述を変更できるので,合併衝突が発生する.この場合,より高いハッシュ (例えば ffffff > 000000) を持つ commit が選択されます.

API

ユーザは会話のメタデータを入手し設定するための 2 つの方法を持っています:

       <method name="updateConversationInfos" tp:name-for-bindings="updateConversationInfos">
           <tp:added version="10.0.0"/>
           <tp:docstring>
               Update conversation's infos (supported keys: title, description, avatar)
           </tp:docstring>
           <arg type="s" name="accountId" direction="in"/>
           <arg type="s" name="conversationId" direction="in"/>
           <annotation name="org.qtproject.QtDBus.QtTypeName.In2" value="VectorMapStringString"/>
           <arg type="a{ss}" name="infos" direction="in"/>
       </method>

       <method name="conversationInfos" tp:name-for-bindings="conversationInfos">
           <tp:added version="10.0.0"/>
           <tp:docstring>
               Get conversation's infos (mode, title, description, avatar)
           </tp:docstring>
           <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="VectorMapStringString"/>
           <arg type="a{ss}" name="infos" direction="out"/>
           <arg type="s" name="accountId" direction="in"/>
           <arg type="s" name="conversationId" direction="in"/>
       </method>

infoは,次のキーを持つ map<str,str>である.

  • モード: 読み込みのみ

  • タイトル

  • 記述

  • avatar: the profile picture

使用されたプロトコル

ゲート

なぜこの選択

Each conversation will be a Git repository. This choice is motivated by:

  1. メッセージの同期と注文が必要です. メークルツリーはそのための完璧な構造であり,枝を合併することによって線性化できます. さらに,Gitで大量に使用されているため,デバイス間の同期が簡単です.

  2. 自然に配布され 大量に使われ バックエンドが多く

  3. ハックや大量に使用された暗号を使ってコミットを確認できます

  4. 必要に応じてデータベースに保存できます

  5. 衝突はファイルではなく メッセージを入力することで回避されます

確認すべきことは

  • git.lockは低くなってしまいます

  • リビギット2のハック

  • 複数の引き出しを同時に?

制限

履歴は削除できません. 会話を削除するには,デバイスは会話から離れ,別の会話を作成する必要があります.

しかし,非常時メッセージ (例えば数分しか読めないメッセージ) は,DRT (タイピングまたは読み書き通知) を介して特別なメッセージを通じて送信できます.

構造

/
 - invited
 - admins (public keys)
 - members (public keys)
 - devices (certificates of authors to verify commits)
 - banned
   - devices
   - invited
   - admins
   - members
 - votes
    - ban
        - members
            - uri
                - uriAdmin
        - devices
            - uri
                - uriAdmin
    - unban
        - members
            - uri
                - uriAdmin
 - CRLs

ファイル転送

This new system overhauls file sharing: the entire history is now kept in sync, so any device in the conversation can instantly access past files. Rather than forcing the sender to push files directly—an approach that was fragile in the face of connection drops and often required manual retries—devices simply download files when they need them. Moreover, once one device has downloaded a file, it can act as a host for others, ensuring files remain available even if the original sender goes offline.

議定書

送信者は次の形式で会話に新しいコミットを追加します:

value["tid"] = "RANDOMID";
value["displayName"] = "DISPLAYNAME";
value["totalSize"] = "SIZE OF THE FILE";
value["sha3sum"] = "SHA3SUM OF THE FILE";
value["type"] = "application/data-transfer+json";

${data_path}/conversation_data/${conversation_id}/${file_id}でリンクを作成します.

その後,受信者は,ファイルをホストするデバイスに連絡して, name="data-transfer://" + conversationId + "/" + currentDeviceId() + "/" + fileIdでチャネルを開いて,ファイルが待っているのかの情報を ${data_path}/conversation_data/${conversation_id}/waitingで保存できます.

接続を受け取るデバイスは,ファイルを送信できるかどうかを確認することによってチャンネルを受信します (sha3sumが正しいとファイルが存在している場合).受信者は最初の開いたチャンネルを保持し,他のチャンネルを閉じて,送信者と同じパスでファイルに書き込む (${data_path}/conversation_data/${conversation_id}/${file_id}) すべての受信データ.

転送が完了またはチャンネルが閉ざされたとき,ファイルが正しいかどうかを確認するためにsha3sumが確認されます (または削除されます).有効であれば,ファイルは待機から削除されます.

失敗の場合 会話のデバイスが 再びオンラインになると 同じ方法で 待ちファイルのすべてを 要求します

Call in Swarm

発想

A swarm conversation can have multiple rendez-vous. A rendez-vous is defined by the following URI:

"accountUri/deviceId/conversationId/confId"では,accountUri/deviceIdがホストを記述する.

ホストは次の2つの方法で決定できます

  • In the swarm metadatas. Where it's stored like the title/desc/avatar (profile picture) of the room

  • 初めの電話者でも

When starting a call, the host will add a new commit to the repository, with the URI to join (accountUri/deviceId/conversationId/confId). This will be valid till the end of the call (announced by a commit with the duration to show)

呼び出しが開始されたと 連絡を受け取り 呼び出しで 加入することができます

攻撃?

  • Avoid Git bombs

記号

設定のタイムスタンプは編集可能なので信頼できます. ユーザーのタイムスタンプだけが信頼できます.

TLS

Git操作,制御メッセージ,ファイル,その他のものは,P2p TLS v1.3 リンクを使用し,PFS を保証する暗号のみを使用します.したがって,各新しい接続のために各鍵が再交渉されます.

DHT (UDP)

携帯にメッセージを送信 (プッシュ通知を起動) や TCP 接続を開始するために使用されます.

ネットワーク活動

招待するプロセス

アリスはボブを招待したい

  1. アリスはボブを会話に加え

  2. Alice generates an invite: { "application/invite+json" : { "conversationId": "$id", "members": [{...}] }}

  3. 通信の2つの可能性 A.接続されていない場合,DHT b.別途,アリスはSIPチャンネルで送信

  4. 誘いを受信すると,クライアントに信号が発信される b.接続されていないので,決して誘いを受信しない.アリスは,ボブはアリスを無視したかどうかわからない必要があります.唯一の方法は,新しいメッセージを通じて新しい誘いを再生することです (次のシナリオ参照)

誰かにメッセージを送信するプロセス

アリスはボブにメッセージを送りたい

  1. アリスはレポにメッセージを追加し,IDを表示します

  2. アリスは成功した場合 (自分自身から) のメッセージを受け取る

  3. アリスとボブが接続されているか否か.両例ではメッセージが作成されます. {"アプリケーション/im-gitmessage-id" : "{"id":"\(convId", "コミット":"\)commitId", "deviceId": "$alice_device_hash"}"}.

  4. ボブには4つの可能性があります. a.ボブはアリスに接続していないので,アリスに信頼している場合は,新しい接続を頼んでbへ行きなさい.b.接続されている場合は,アリスから連絡を取り,新しいメッセージを発表してください. c.ボブはその会話を知らない.DHTを通じ最初に招待状を取得してその会話を受け入れるようにお願いします ({"アプリケーション/招待状",会話Id}) d.ボブは接続を断ち切っている (ネットワークがない,または単に閉鎖されている).彼は新しいメッセージを受け取らないが,次の接続が起こるときに同期しようとします

実施

図書: 群衆チャット教室

Supported messages

Initial message

{
    "type": "initial",
    "mode": 0,
    "invited": "URI"
}

Represents the first commit of a repository and contains the mode:

enum class ConversationMode : int { ONE_TO_ONE = 0, ADMIN_INVITES_ONLY, INVITES_ONLY, PUBLIC }

and invited if mode = 0.

Text message

{
    "type": "text/plain",
    "body": "content",
    "react-to": "id (optional)"
}

Or for an edition:

{
    "type": "application/edited-message",
    "body": "content",
    "edit": "id of the edited commit"
}

発信

Show the end of a call (duration in milliseconds):

{
    "type": "application/call-history+json",
    "to": "URI",
    "duration": "3000"
}

Or for hosting a call in a group (when it starts)

{
    "type": "application/call-history+json",
    "uri": "host URI",
    "device": "device of the host",
    "confId": "hosted confId"
}

A second commit with the same JSON + duration is added at the end of the call when hosted.

Add a file

{
    "type": "application/data-transfer+json",
    "tid": "unique identifier of the file",
    "displayName": "File name",
    "totalSize": "3000",
    "sha3sum": "a sha3 sum"
}

totalSize is in bits,

Updating profile

{
    "type": "application/update-profile",
}

Member event

{
    "type": "member",
    "uri": "member URI",
    "action": "add/join/remove/ban"
}

When a member is invited, join or leave or is kicked from a conversation

Vote event

Generated by administrators to add a vote for kicking or un-kicking someone.

{
    "type": "vote",
    "uri": "member URI",
    "action": "ban/unban"
}

!! 古いドラフト!!

注釈

Following notes are not organized yet. Just some line of thoughts.

暗号化改良

グループチャット機能では,重要な暗号も必要です.現在のデザインでは,会話の以前のDHT値として証明書が盗まれた場合,会話が解読されることがあります.

注釈

A lib might exist to implement group conversations.

OpenDHTでECC支援が必要

使用

役を追加する?

グループチャットには 2つの主要な用途があります

  1. 企業における マターモストのようなもの, プライベートチャンネル, 特定の役割 (admin/spectator/bot/etc) または教育 (少数が活動している)

  2. 横向きな会話は 友人の会話のように

Jami will be for which one?

実施アイデア

役割の旗でユーザーをサインするグループのための証明書.追加または撤回することもできます.

話し合いに参加する

  • 直接招待のみ

  • リンク/QRコード/何であれ

  • 部屋名で?

必要なもの

  • 秘密主義:グループチャット以外のメンバーはグループ内のメッセージを読むことができない

  • 秘密保持: グループからの鍵が侵害された場合,以前のメッセージは機密に保たれる (可能な限り)

  • メッセージの順序: メッセージの順序が正しい必要がある

  • 通信を同期する: また,できるだけ早くすべてのメッセージが届くようにする必要があります.

  • 持続性:実際には,DHT上のメッセージは10分しか続かない.この種のDHTのために計算された最高のタイミングであるため.データを維持するには,ノードは10分ごとにDHTの値を再設定する必要があります.ノードがオフラインであるときに行うもう一つの方法は,ノードがデータを再入力することを許すことです.しかし,10分後,8ノードがまだここにある場合は,64のリクエストを行います (それは指数値です).そのためのスパムを避ける現在の方法はクエリです.これはまだ64のリクエストを行いますが,最大冗長を8のノードに制限します.

他の分布式方式

  • IPFS: 調べる必要がある

  • 調べる必要がある

  • 捜査が必要

既存の作業に基づいて

グループチャットは,既に複数のデバイスで実施されている同じ作業に基づいたもの (しかし,ここでグループ証明書を使用します).

  1. データベースをクライアントから デイモンに移動させる

  2. 接続ができない場合,同期は行われず,その人は会話を見ることができません

専用DHTの1つ

超ユーザの DHT みたいだ

What's next for file transfers

Currently, the file transfer algorithm is based on a TURN connection (See ファイル転送). In the case of a big group, this will be bad. We first need a P2P connection for the file transfer. Implement the RFC for P2P transfer.

Other problem: currently there is no implementation for TCP support for ICE in PJSIP. This is mandatory for this point (in PJSIP or homemade)

資源