レビュー:コミュニティにDiscord風のビデオとボイスルームを追加する 🎙

スマホ版では部屋の作成はできるものの、既存の部屋をクリックしても入室できないようです。/resenha/r/topicに直接アクセスすると開くことはできるのですが、これはバグでしょうか?

私のスマホでは問題なく動作しています。今週、Discourse インスタンスを更新しましたか?

実験的なプラグインは頻繁な更新が必要です

「いいね!」 5

今月は多くのアップデートがありましたが、主なものは LiveKit を通じた SFU のオプションかつルーム単位でのサポートです。

完全な P2P WebRTC は依然としてメインかつデフォルトのサポートトランスポートですが、SFU も今では1つのルームで数百人の参加者をサポートする必要がある人々にも利用可能です。

また、多くの改善点も取り入れました。例えば、ルームとウィジェットコントロールでのオーディオとビデオデバイスピッカー、チャットと投稿での # オートコンプリートによる Resenha ルームのメンション可能化、ルームレイアウトオプションなどです。

「いいね!」 15

この件、ありがとうございます。SFU がまさに不足していた部分でした。これが当初、私に別のフォークの維持を促した理由です。アップストリームでサポートされるようになった今、フォークを終了し、resenha を直接追跡できます。

LiveKit については、その方向に進みたいかどうか分からなかったため、質問を控えていました。今、その方向に進むことになったとして、機能や小さな改善のための PR を受け入れていただけますか?

「いいね!」 4

@Falco こんにちは。更新された resenha のテスト中に、再現可能な問題がいくつか見つかりました。upstream に役立てば幸いですので、調査結果とローカルで適用しているパッチを共有します。

1. Admin UI が room_type を無音で破棄し、ステージルームが固定されない
app/controllers/resenha/admin_rooms_controller.rb:65 (room_params) で :room_type が permit リストから除外されており、admin_room_serializer.rb でもシリアライズされていません。

Admin UI 経由で行われたすべてのステージ割り当てが破棄され、ルームは「open」として作成され、後続の Admin 編集でも「open」に戻ってしまいます。本番ログで確認済みです。ユーザー向けコントローラーでは許可されていますが、Admin 経路でのみ失われています。

# admin_rooms_controller.rb — permit リストに :room_type を追加し、その後:
if permitted.key?(:room_type)
  value = Resenha::Room::ROOM_TYPES[permitted[:room_type].to_s]
  raise Discourse::InvalidParameters.new(:room_type) if value.nil?
  permitted[:room_type] = value
end
# admin_room_serializer.rb — room_type をシリアライズし、フォームが正しく初期化されるようにします

2. 無効な room_type が無音で open にフォールバックする
app/controllers/resenha/rooms_controller.rb:575ROOM_TYPES[...] || ROOM_TYPE_OPEN

それ以外に有効なルーム編集において、形成不良または古い room_type が存在すると、ステージルームが静かに open に切り替わります。400 エラーを返すことで、問題のある呼び出し元を可視化し、ルームの破損を防ぐことができます。

value = Resenha::Room::ROOM_TYPES[permitted[:room_type].to_s]
raise Discourse::InvalidParameters.new(:room_type) if value.nil?
permitted[:room_type] = value

3. ハートビートが退室したばかりのユーザーを復活させる(ゴーストプレゼンス)
rooms_controller.rb:234 (heartbeat) は無条件にプレゼンスを再追加するため、leave (:220) の処理中にハートビートが送られてくると、それが後に到達し、退室したユーザーを再作成してしまいます。
このゴーストは TTL による回収まで存在し、ブロードキャストされないため、クライアントは最大1分間ユーザーを「ルーム内」として表示し続けます。

デバイス上で再現確認済みです。キックでも同様の問題が発生します。

# ParticipantTracker: 15秒のトームストーン
def mark_left(room_id, user_id)  = redis.setex(left_key(room_id, user_id), 15, "1")
def recently_left?(room_id, user_id) = redis.exists?(left_key(room_id, user_id))
# leave/kick → mark_left; join/livekit_token → clear_left; heartbeat:
return head :no_content if Resenha::ParticipantTracker.recently_left?(@room.id, current_user.id)

4. 古い participant_left ウェブフックが新しいセッションをファントムキックする
livekit_webhooks_controller.rb:37/57 — 退室はユーザーIDのみでマッチングされます。
迅速な切断/再接続時、前任のセッションの participant_left が遅れて到着し、新しい セッションのプレゼンスを失効させます(ユーザーは再接続から約3秒後に「キック」され、約15秒後に戻ります)。
デバイス上で再現確認済みです。再接続が旧セッションの切断よりも前である場合、gone_at ヒューリスティックはセッションを区別できません。

# participant_joined → ライブ SID を記録
Resenha::ParticipantTracker.set_livekit_sid(room.id, user_id, event.dig("participant", "sid"))
# expire_participant → 前任のセッションの退室をスキップ
known = Resenha::ParticipantTracker.livekit_sid(room.id, user_id)
return if sid.present? && known.present? && sid != known

5. 最後の退室後の DeleteRoom 404 がログを洪水状態にする
lib/resenha/livekit/room_service_client.rb:84 は 200 以外のすべてのレスポンスで警告を発します。
SFU はルームが空になった瞬間に自動的にルームを閉じるため、最後の退室時の DeleteRoom はこれと競合し、「要求されたルームが存在しません」という状態は障害ではなく期待される終了状態です。
これにより、最後の退室のたびに Logster に記録されます。

elsif method == "DeleteRoom" && response.status == 404
  Rails.logger.debug("[resenha-livekit] DeleteRoom no-op for room #{room.id}: already gone")
  true

必要であればプルリクエストを送信できます。

以前述べた通り、あなたの方向性を完全に把握しているわけではありませんが、私が投稿したこちらの記事 Discourse Desktop Mac App - #10 by nicolsdennis をご覧いただければ参考になるかもしれません。

「いいね!」 2

これは本当に素晴らしいアイデアです。ライブストリーム機能と連携させることで、チャットチャンネルを統合した美しい体験として提供できるでしょう。

「いいね!」 4

こんにちは。ルーム名を変更しても、スラグが更新されません。また、ルームの削除もできず、サーバーエラーが発生します。

ルームの順序や表示方法を視覚的に変更できる機能があれば、さらに便利だと思います。

詳細なレポートをありがとうございます。それらに関するPRをマージしました:

「いいね!」 6

プライベートボイスルームに関連するいくつかの小さなUI/UXの件があります:

1. プライベート/ロックのマイコンが小さすぎる

部屋のプライバシー状態を示すアイコンがあるのは素晴らしいですが、残念ながら小さすぎて、他のアイコンと重なりがちです。また、サイドバーの他の部分と一貫性がありません:

image   image

2. 参加者リストが見つかりにくい

プライベートボイスルームの参加者リストは、通話中からしかアクセスできません。

これはあまり直感的ではありません。ボイスルームが非アクティブな状態でも、利用可能な設定から参加者/招待者を編集できることを期待しています。非アクティブな状態でも多くの設定(公開/プライベート、最大参加者数など)が利用可能ですが、実際の参加者リストは含まれていません。

「いいね!」 3

その両方の修正を行いました。@nathank さん、報告ありがとうございます!

「いいね!」 2

href リンクから特定のルームにリンクすることは可能でしょうか?UX を簡素化するために、単一のテストルームへのショートカットを追加したいと考えています。

ええ、この形式では今可能になりました

https://discourse-on-a-pi5.falco.dev/resenha/r/watercooler

「いいね!」 4

最近の改善点も注目すべきです:

coturn authによるプライベートSTUN/TURNのサポート

これにより、coturnインスタンスを自分だけで使用できるように制限することができ、DiscourseとCoturn間で共有シークレットを設定することで非常に簡単に設定できます。

LiveKit使用時のセッション録画のサポート

すべて呼び出しUIから、1クリックで録画開始、1クリックで停止。

通話参加者のフラグサポート

フラグは文脈を欠くものの、ユーザーはテキストエリアから提供できます。

ビデオタイルの右クリックメニュー

ピアの音量調整やキックなどが簡単に行えます。

音声、ビデオ、画面共有のより高品質なオプション

今週のお気に入り機能で、これによりユーザーはより高いビットレート制限をオプトインし、より良い音声/ビデオを得ることができます。

「いいね!」 6

随分良くなりました!!!お聞きいただき(そして対応していただき)、ありがとうございます!!

image

「いいね!」 2

これは私のインスタンスの問題でしょうか、それとも調査すべき問題でしょうか?管理パネルからボイスルームを削除しようとした際に、エラー500が発生しています。

ActiveRecord::InvalidForeignKey (PG::ForeignKeyViolation: ERROR:  "resenha_rooms"テーブルでの更新または削除が、"resenha_sessions"テーブルの外部キー制約"fk_rails_ID"に違反しました DETAIL:  キー (id)=(1) はまだ"resenha_sessions"テーブルから参照されています。
「いいね!」 1

報告ありがとうございます。修正がマージされました

「いいね!」 2

超高速な修正、ありがとうございます。期待通り動作しました。

少し補足ですが、デフォルトのルーム名を変更しても、パス /resenha/r/watercooler は更新されませんでした。ただし、以前のデフォルトルームを削除して、新しいものを追加することはできました。

「いいね!」 1

スラッグを明示的に編集可能に設定したので、カテゴリーと同じように動作します

「いいね!」 6

特定の方式で開くために、いくつかのURLパラメータを追加することもできます:

https://discourse-on-a-pi5.falco.dev/resenha/r/watercooler?join は、部屋に直接入り、「参加」ボタンをクリックする必要はありません。

https://discourse-on-a-pi5.falco.dev/resenha/r/watercooler?join&widget(今週の前半に追加)は、ウィジェットモードで開きます。

https://discourse-on-a-pi5.falco.dev/resenha/r/watercooler?join&chat は、チャットモードで開きます。

「いいね!」 2