Parece que en la versión móvil solo se pueden crear salas, pero al hacer clic directamente en una sala ya creada no se puede entrar. Sin embargo, si accedes directamente a /resenha/r/topic, sí se puede abrir. ¿Es esto un error?
Funciona perfectamente en mi teléfono. ¿Has actualizado tu instancia de Discourse esta semana?
Los complementos experimentales requieren actualizaciones frecuentes
Este mes ha habido muchas actualizaciones, pero la principal es el soporte opcional y por sala para SFU mediante LiveKit.
El transporte principal y predeterminado sigue siendo WebRTC P2P completo, pero ahora también se admite SFU para quienes necesitan dar soporte a cientos de participantes en una sola sala.
También hemos realizado muchas mejoras, como selectores de dispositivos de audio y vídeo en los controles de sala y widgets, la posibilidad de mencionar salas de Resenha mediante autocompletado con # en chats y publicaciones, opciones de diseño de sala, entre otras.
Gracias por esto, la SFU era la pieza que realmente faltaba. Fue lo que me impulsó originalmente a mantener un fork separado; ahora que está soportado en el proyecto principal, puedo dejar de mantener el fork y seguir a resenha directamente.
Me había contenido de preguntar sobre LiveKit porque no sabía si querías ir en esa dirección. Ahora que sí: ¿estás abierto a PRs para nuevas características y pequeñas mejoras?
@Falco Hola, he encontrado varios problemas reproducibles mientras probaba la versión actualizada de resenha. Comparto mis hallazgos y los parches que estoy aplicando localmente, por si resultan útiles para el proyecto principal.
1. La interfaz de administración descarta silenciosamente room_type; las salas de etapa nunca pueden mantenerse
app/controllers/resenha/admin_rooms_controller.rb:65 (room_params) omite :room_type de la lista de parámetros permitidos, y admin_room_serializer.rb nunca lo serializa.
Cada asignación de etapa realizada a través de la interfaz de administración se pierde; las salas se crean como abiertas y “vuelven” a ser abiertas en cualquier edición posterior desde la administración. Confirmado mediante los registros de producción; el controlador visible para el usuario lo permite, solo la ruta de administración lo perdió.
# admin_rooms_controller.rb — añade :room_type a la lista de permitidos, luego:
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 — serializa room_type para que el formulario se inicialice correctamente
2. Un room_type no válido vuelve silenciosamente a “abierta”
app/controllers/resenha/rooms_controller.rb:575 — ROOM_TYPES[...] || ROOM_TYPE_OPEN.
Cualquier room_type mal formado o obsoleto en una edición de sala válida convierte silenciosamente una sala de etapa en abierta. Un error 400 hace visible al cliente que causa el mal comportamiento, en lugar de corromper la sala.
value = Resenha::Room::ROOM_TYPES[permitted[:room_type].to_s]
raise Discourse::InvalidParameters.new(:room_type) if value.nil?
permitted[:room_type] = value
3. El heartbeat resucita a un usuario que acaba de salir (presencia fantasma)
rooms_controller.rb:234 (heartbeat) vuelve a añadir la presencia incondicionalmente, por lo que un heartbeat en tránsito cuando se procesa leave (:220) llega después y vuelve a crear al usuario que se ha ido.
El fantasma persiste hasta que se elimina por TTL, lo cual no se transmite — los clientes muestran al usuario “en la sala” durante hasta un minuto.
Reproducido en dispositivo; la expulsión tiene la misma vulnerabilidad.
# ParticipantTracker: tumba de 15s
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. Un webhook participant_left obsoleto expulsa fantasmalmente una sesión nueva
livekit_webhooks_controller.rb:37/57 — las salidas se coinciden solo por identidad de usuario.
En una desconexión/reconexión rápida, el participant_left de la sesión reemplazada llega tarde y expira la presencia de la nueva sesión (el usuario es “expulsado” ~3s después de reconectar, vuelve ~15s después).
Reproducido en dispositivo; la heurística gone_at no puede distinguir las sesiones cuando la reconexión antecede a la desconexión de la sesión antigua.
# participant_joined → registra el SID en vivo
Resenha::ParticipantTracker.set_livekit_sid(room.id, user_id, event.dig("participant", "sid"))
# expire_participant → omite la salida de una sesión reemplazada
known = Resenha::ParticipantTracker.livekit_sid(room.id, user_id)
return if sid.present? && known.present? && sid != known
5. DeleteRoom 404 después de la última salida inunda los registros
lib/resenha/livekit/room_service_client.rb:84 advierte sobre cualquier respuesta no 200.
El SFU cierra automáticamente una sala en el momento en que se vacía, por lo que el DeleteRoom de la última salida compite rutinariamente con ello — “la sala solicitada no existe” es el estado final deseado, no un fallo.
Aparece en Logster en cada última salida.
elsif method == "DeleteRoom" && response.status == 404
Rails.logger.debug("[resenha-livekit] DeleteRoom no-op for room #{room.id}: already gone")
true
Puedo enviar una pull request si lo deseas.
Como dije antes, no conozco completamente tu dirección, pero puedes echar un vistazo a la mía ya que he hecho una publicación aquí → Discourse Desktop Mac App - #10 by nicolsdennis
Esto sería absolutamente brillante: tendría sentido integrarlo con el mecanismo de transmisión en vivo, lo cual proporcionaría el canal de chat asociado como parte de una experiencia integrada y hermosa.
Hola, al cambiar el nombre de la sala, no se actualiza el slug. Además, no me deja eliminar salas; me da un error del servidor.
También sería genial poder cambiar visualmente el orden de las salas y cómo se muestran.
Gracias por el informe detallado, acabo de fusionar un PR para eso:
Tengo un par de detalles menores de interfaz/UX relacionados con las salas de voz privadas:
1. El microicono de privado/candado es demasiado pequeño.
Es genial que tengamos un icono que indique el estado de privacidad de una sala; lamentablemente, es demasiado pequeño y se superpone mucho con el icono. Además, es inconsistente con el resto de la barra lateral:
![]()
2. La lista de participantes es difícil de encontrar
Solo puedes acceder a la lista de participantes de una sala de voz privada desde dentro de la llamada en sí.
Esto no es muy intuitivo. Espero poder modificar los participantes/invitados desde la configuración disponible cuando la sala de voz está inactiva. De hecho, hay abundantes opciones de configuración disponibles cuando está inactiva (incluidas pública vs privada, número máximo de participantes, etc.), simplemente no la lista de participantes actual.
He realizado correcciones para ambos, ¡gracias por el reporte, @nathank!
Me pregunto si es posible vincular una sala específica mediante enlaces href. Quiero añadir un acceso directo a una única sala de prueba para simplificar nuestra experiencia de usuario.
Sí, ahora es posible en este formato
También merece la pena destacar las mejoras recientes:
Soporte para STUN/TURN privados mediante autenticación de coturn
Esto te permite mantener tu instancia de coturn restringida para ti, y es muy fácil de configurar con un secreto compartido entre Discourse y Coturn.
Soporte para grabación de sesiones al usar LiveKit
Todo ello desde la interfaz de la llamada, un solo clic para iniciar la grabación, un solo clic para detenerla.
Soporte para indicadores en los participantes de la llamada
Aunque el indicador carecerá de contexto, los usuarios pueden proporcionarlo a través del área de texto.
Menú de clic derecho en los mosaicos de vídeo
Fácil ajuste del volumen de un participante, expulsión, etc.
Calidad superior opcional para voz, vídeo y compartición de pantalla
Mi característica favorita de la semana, esto permite a los usuarios optar por límites de bitrate mucho más altos, y obtener una calidad de audio/vídeo mucho mejor.
¿Es un problema de mi instancia o probablemente algo que debería investigar? Estoy recibiendo un error 500 al intentar eliminar salas de voz desde el panel de administración:
ActiveRecord::InvalidForeignKey (PG::ForeignKeyViolation: ERROR: update or delete on table "resenha_rooms" violates foreign key constraint "fk_rails_ID" on table "resenha_sessions" DETAIL: Key (id)=(1) is still referenced from table "resenha_sessions".
Gracias por el informe, la corrección ya se ha integrado
Gracias por esta corrección ultrarrápida; funcionó como se esperaba.
Solo una pequeña nota a modo de seguimiento: cambiar el nombre de la sala predeterminada no actualizó la ruta /resenha/r/watercooler, pero ahora pude eliminar la sala predeterminada anterior y añadir una nueva.
He hecho que el slug sea explícitamente editable ahora, así que funciona como las categorías
También puedes agregar algunos parámetros de URL para abrir de una manera específica:
https://discourse-on-a-pi5.falco.dev/resenha/r/watercooler?join, simplemente ingresa a la sala, sin botón de clic para unirse
https://discourse-on-a-pi5.falco.dev/resenha/r/watercooler?join&widget (agregado a principios de esta semana), se abre y se convierte en modo widget
https://discourse-on-a-pi5.falco.dev/resenha/r/watercooler?join&chat se abre en modo chat

