请问在手机端好像只能创建房间但是直接点击已经创建的房间进不去,如果直接访问/resenha/r/topic是可以打开的,这是否是一个bug
在我的手机上运行良好,你本周是否更新了你的 Discourse 实例?
实验性插件需要频繁更新
本月更新内容很多,但主要更新是可选的、基于房间的 LiveKit SFU 支持。
全 P2P WebRTC 仍然是主要且默认支持的传输方式,但现在也支持 SFU,以满足需要在单个房间中容纳数百名参与者的用户的需求。
我们还进行了许多改进,例如在房间和控件中添加音频和视频设备选择器,使 Resenha 房间可以通过聊天和帖子中的 # 自动补全提及,房间布局选项等。
谢谢,SFU 确实是缺失的关键部分。正是它最初促使我维护一个独立的分支;现在上游已经支持它,我可以放弃这个分支并直接跟踪 resenha。
我之前没有询问 LiveKit 的情况,因为我不确定你是否想朝那个方向发展。既然你现在已经做了:你是否愿意接受关于功能和小型改进的 PR?
@Falco 嘿,我在测试更新后的 resenha 时遇到了一些可复现的问题。分享我的发现以及我本地正在运行的补丁,以防它们对上游开发有用。
1. 管理 UI 静默丢弃 room_type,导致房间无法保持阶段状态
app/controllers/resenha/admin_rooms_controller.rb:65(room_params)在允许参数列表中省略了 :room_type,且 admin_room_serializer.rb 从未序列化它。
通过管理 UI 进行的每次阶段分配都会被丢弃,房间创建为开放状态,并在任何后续的管理编辑中“恢复”为开放状态。已通过生产日志确认;面向用户的控制器允许该参数,仅管理路径丢失了它。
# admin_rooms_controller.rb — 在允许列表中添加 :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 静默回退为开放状态
app/controllers/resenha/rooms_controller.rb:575 — ROOM_TYPES[...] || ROOM_TYPE_OPEN。
在任何其他方面有效的房间编辑中,任何格式错误/过期的 room_type 都会悄悄地将阶段房间翻转为开放状态。返回 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 回收,而回收不会广播——客户端显示他们“在房间内”长达一分钟。
已在设备上复现;踢出具有相同的暴露问题。
# 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 webhook 幻影踢出新鲜会话
livekit_webhooks_controller.rb:37/57 — 离开仅通过用户身份匹配。
在快速断开/重新连接时,被取代会话的 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
这绝对太棒了——将其与直播机制挂钩会非常合理,这样可以提供相关的聊天频道,带来完美的一体化体验。
你好,更改房间名称时,slug 不会更新。此外,我无法删除房间——会收到服务器错误。
如果还能直观地调整房间的排序及其显示方式,那就更好了。
感谢详细的报告,刚刚合并了一个针对这些问题的 PR:
我有几个关于私密语音房间的次要 UI/UX 问题:
1. 私密/锁定小图标太小了。
很高兴我们有一个图标来指示房间的隐私状态;不幸的是,它太小了,并且与图标重叠很多。而且与侧边栏的其余部分不一致:
![]()
2. 参与者列表很难找到
你只能在语音通话内部才能访问私密语音房间的参与者列表。
这不是很直观。我希望能够在语音房间不活跃时,从可用的设置中修改参与者/邀请人。当它不活跃时,确实有大量可用的设置(包括公开与私密、最大参与者数等),只是没有实际的参与者列表。
我已经修复了这两个问题,感谢 @nathank 的报告!
我在想,是否可以通过 href 链接直接跳转到特定的房间?我想为单个测试房间添加一个快捷方式,以简化我们的用户体验。
同样值得关注的近期改进:
支持通过 coturn auth 使用私有 STUN/TURN
这允许您将 coturn 实例限制为仅您自己使用,并且通过 Discourse 和 Coturn 之间的共享密钥进行配置非常简单。
支持使用 LiveKit 时录制会话
所有操作均可通过通话界面完成,单击即可开始录制,单击即可停止。
支持为通话参与者设置标记
虽然标记本身缺乏上下文,但用户可以通过文本区域提供相关信息
视频图块上的右键菜单
可以轻松调整同伴的音量,或将其踢出等。
可选择启用更高品质的语音、视频和屏幕共享
这是我本周最喜欢的功能,它允许用户选择启用更高的比特率限制,从而获得更好的音频/视频质量。
这是我自己实例的问题,还是可能需要进一步调查的情况?当我尝试从管理面板中移除语音房间时,收到了 500 错误:
ActiveRecord::InvalidForeignKey (PG::ForeignKeyViolation: ERROR: 对表 "resenha_rooms" 的更新或删除违反了表 "resenha_sessions" 上的外键约束 "fk_rails_ID" DETAIL: 键 (id)=(1) 仍被表 "resenha_sessions" 引用。
感谢报告,修复已合并
感谢您提供这个超快速的修复方案;它按预期正常工作。
顺便补充一个小提示:更改默认房间名称并未更新路径 /resenha/r/watercooler,但我现在能够移除之前的默认房间并添加一个新的房间。
我现在已将 slug 设置为显式可编辑,因此它的工作方式与分类相同
您还可以添加一些 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,以聊天模式打开

