asopi tech
asopi techIndie Developer

Asopitech With · ボイス・チャットのコミュニティ

Discord オンライン状態 with Alopex Chirps

Discordのオンライン状態は、ボイス・チャットのコミュニティのDiscordで、友だちやメンバーが今オンラインかどうかを見せる機能です。これをAlopex Chirpsを応用して再現すると…?

更新: 2026/10/13

どんなサービスか

Discordでは、ユーザーの名前の横に、オンライン、退席中、取り込み中、オフラインといった状態が出ます。友だちやサーバーのメンバーの状態は、変わるとすぐに相手の画面に反映されます。扱うデータは、ユーザーごとの状態と、その状態を見ている相手です。

通信の組み立て

  • ノードのメンバーシップ:ユーザーの接続を受けるサーバーをノードとしてメッシュに入れます。gossipで、どのノードが動いているかを全ノードが知ります。
  • 状態の配信:ユーザーの状態が変わったら、そのユーザーを見ている相手がつながるノードへ送ります。宛先が多いときは、全ノードへの配信を使います。古くなってもかまわない状態の通知は、一時的な配信方式で送ります。
  • ノードの離脱:ノードが止まると、離脱のイベントが届きます。そのノードにつながっていたユーザーを、まとめてオフラインにできます。

どのユーザーがどのノードにつながっているか、誰が誰の状態を見ているかは、アプリが持ちます。

配置の形

接続を受けるサーバーの各ノードにChirpsを組み込みます。ノードを足すときは、シードのリストから参加させるだけで、ほかのノードに伝わります。

Alopex Chirpsが合う理由

オンライン状態の配信は、ノードどうしの素早い通知と、ノードが止まったことの検知でできています。Chirpsは、送信と全体への配信と、gossipによる故障検知を、同じライブラリで持ちます。

コードで見る

ノードをまたぐ状態変化に一貫した順序を与える、ハイブリッド論理時計の中心だけを取り出したコードです(Rust)。

use alopex_chirps_gossip_swim::hlc::{Clock, LocalHlc};
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Arc;
use std::time::Duration;

// 説明用の手動クロック(実際はシステム時計)
struct ManualClock(AtomicU64);
impl Clock for ManualClock {
    fn now_millis(&self) -> u64 {
        self.0.load(Ordering::SeqCst)
    }
}

fn main() {
    let skew = Duration::from_secs(1);
    // 接続を受ける 2 つのノード A / B。それぞれ論理時計を持つ
    let mut a = LocalHlc::with_clock(skew, Arc::new(ManualClock(AtomicU64::new(100))));
    let mut b = LocalHlc::with_clock(skew, Arc::new(ManualClock(AtomicU64::new(90))));

    // A 側で状態の変化(オンライン→退席)が起きるたびに時計を進める
    let online = a.tick();
    let away = a.tick();
    println!("A: online={online:?} away={away:?}");

    // A の変化を B が受け取ると、B の時計は A を追い越す
    let seen = b.receive(away).expect("receive");
    println!("B receives A: {seen:?}");

    // その後 B 側で起きた変化は、必ず A の変化より後に順序づく
    let b_change = b.tick();
    println!("B next: {b_change:?}");
    assert!(b_change > away);
    println!("OK: どのノードも、状態変化を同じ順序で解釈できる");
}

ハイブリッド論理時計で、ノードをまたいだ状態変化に一貫した順序がつき、最新の状態が全員で一致します。どのノードが動いているか(gossipメンバーシップ)と配信は、本文のとおりChirpsが受け持ちます。

ノードどうしの配信と故障の検知を同じライブラリで扱えるAlopex Chirpsで、オンライン状態の配信を作ってみよう。GitHubのクイックスタートから始められます。

関連リンク