mirror of
https://github.com/element-hq/synapse.git
synced 2026-08-28 02:54:50 +00:00
Add support for specifying the SFU WebSocket URL together with configured LiveKit transports (#20146)
Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
This commit is contained in:
co-authored by
Andrew Morgan
parent
781d08df26
commit
c246d81dec
@@ -0,0 +1 @@
|
||||
Deprecate `livekit_service_url` and add support for specifying the SFU WebSocket URL for configured LiveKit transports. Please check [the relevant section in the upgrade notes](https://github.com/element-hq/synapse/blob/develop/docs/upgrade.md#upgrading-to-v11600).
|
||||
@@ -118,6 +118,20 @@ stacking them up. You can monitor the currently running background updates with
|
||||
[the Admin API](usage/administration/admin_api/background_updates.html#status).
|
||||
|
||||
|
||||
# Upgrading to v1.161.0
|
||||
|
||||
## Deprecation of `matrix_rtc.livekit_service_url`
|
||||
|
||||
When configuring the MatrixRTC LiveKit transport, the `livekit_service_url` is now
|
||||
deprecated but should continue to be listed to ensure backwards compatibility with
|
||||
older clients. A new sibling `url` config property is added that should be set to
|
||||
your SFU's WebSocket URL. Clients that support `url` will use the Client-Server API
|
||||
to (indirectly) interact with the LiveKit authorization service. The service needs
|
||||
to be set up as an application service in order to support these endpoints. See
|
||||
https://github.com/element-hq/lk-jwt-service and
|
||||
https://element-hq.github.io/synapse/v1.161/usage/configuration/config_documentation.html#matrix_rtc
|
||||
for further details.
|
||||
|
||||
# Upgrading to v1.159.0
|
||||
|
||||
## Change of signing key expiry date for the Debian/Ubuntu package repository (2026)
|
||||
|
||||
@@ -2662,13 +2662,20 @@ This setting has the following sub-options:
|
||||
|
||||
* `type` (string): The type of transport to use to connect to the selective forwarding unit (SFU).
|
||||
|
||||
* `livekit_service_url` (string): The base URL of the LiveKit service. Should only be used with LiveKit-based transports.
|
||||
* `url` (string): The WebSocket URL of the LiveKit SFU. If type is "livekit", either this or `livekit_service_url` is required.
|
||||
|
||||
Clients that support `url` will use the Client-Server API to (indirectly) interact with the LiveKit authorization service. The service needs to be set up as an application service in order to support these endpoints. See https://github.com/element-hq/lk-jwt-service for further details.
|
||||
|
||||
* `livekit_service_url` (string): Deprecated. The HTTP URL of the LiveKit authorization service. If type is "livekit", either this or `url` is required.
|
||||
|
||||
Clients that don't support `url` will use `livekit_service_url` to directly interact with the LiveKit authorization service. This mode of operation is deprecated and should only be used for backwards compatibility.
|
||||
|
||||
Example configuration:
|
||||
```yaml
|
||||
matrix_rtc:
|
||||
transports:
|
||||
- type: livekit
|
||||
url: wss://livekit.example.com
|
||||
livekit_service_url: https://matrix-rtc.example.com/livekit/jwt
|
||||
```
|
||||
---
|
||||
|
||||
@@ -3022,10 +3022,28 @@ properties:
|
||||
type: string
|
||||
description: The type of transport to use to connect to the selective forwarding unit (SFU).
|
||||
example: livekit
|
||||
url:
|
||||
type: string
|
||||
description: >-
|
||||
The WebSocket URL of the LiveKit SFU. If type is "livekit", either this or `livekit_service_url` is
|
||||
required.
|
||||
|
||||
|
||||
Clients that support `url` will use the Client-Server API to (indirectly) interact with the LiveKit
|
||||
authorization service. The service needs to be set up as an application service in order to support
|
||||
these endpoints. See https://github.com/element-hq/lk-jwt-service for further details.
|
||||
example:
|
||||
wss://livekit.example.com
|
||||
livekit_service_url:
|
||||
type: string
|
||||
description: >-
|
||||
The base URL of the LiveKit service. Should only be used with LiveKit-based transports.
|
||||
Deprecated. The HTTP URL of the LiveKit authorization service. If type is "livekit", either this or `url` is
|
||||
required.
|
||||
|
||||
|
||||
Clients that don't support `url` will use `livekit_service_url` to directly interact with the LiveKit
|
||||
authorization service. This mode of operation is deprecated and should only be used for backwards
|
||||
compatibility.
|
||||
example: https://matrix-rtc.example.com/livekit/jwt
|
||||
description: A list of transport types and arguments to use for MatrixRTC connections.
|
||||
default: []
|
||||
@@ -3033,6 +3051,7 @@ properties:
|
||||
examples:
|
||||
- transports:
|
||||
- type: livekit
|
||||
url: wss://livekit.example.com
|
||||
livekit_service_url: https://matrix-rtc.example.com/livekit/jwt
|
||||
enable_registration:
|
||||
type: boolean
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
from typing import Any
|
||||
|
||||
from pydantic import Field, StrictStr, ValidationError, model_validator
|
||||
from pydantic import Field, StrictStr, ValidationError, field_validator, model_validator
|
||||
from typing_extensions import Self
|
||||
|
||||
from synapse.types import JsonDict
|
||||
@@ -29,20 +29,34 @@ from ._base import Config, ConfigError
|
||||
class TransportConfigModel(ParseModel):
|
||||
type: StrictStr
|
||||
|
||||
url: StrictStr | None = Field(default=None)
|
||||
"""An optional WebSocket URL pointing to the LiveKit SFU. If type is "livekit", either this or livekit_service_url is required."""
|
||||
|
||||
livekit_service_url: StrictStr | None = Field(default=None)
|
||||
"""An optional livekit service URL. Only required if type is "livekit"."""
|
||||
"""Deprecated. An optional HTTP URL pointing to the LiveKit authorization service. If type is "livekit", either this or url is required."""
|
||||
|
||||
@model_validator(mode="after")
|
||||
def validate_livekit_service_url(self) -> Self:
|
||||
if self.type == "livekit" and not self.livekit_service_url:
|
||||
def validate_livekit_transport(self) -> Self:
|
||||
if self.type == "livekit" and not self.url and not self.livekit_service_url:
|
||||
raise ValueError(
|
||||
"You must set a `livekit_service_url` when using the 'livekit' transport."
|
||||
"You must set either `url` or `livekit_service_url` when using the 'livekit' transport."
|
||||
)
|
||||
return self
|
||||
|
||||
|
||||
class MatrixRtcConfigModel(ParseModel):
|
||||
transports: list = []
|
||||
transports: list[dict[str, Any]] = []
|
||||
|
||||
@field_validator("transports")
|
||||
@classmethod
|
||||
def validate_transports(
|
||||
cls, transports: list[dict[str, Any]]
|
||||
) -> list[dict[str, Any]]:
|
||||
"""Validate each transport by attempting to construct a `TransportConfigModel`
|
||||
from it, raising a `ValidationError` if construction fails."""
|
||||
for transport in transports:
|
||||
TransportConfigModel(**transport)
|
||||
return transports
|
||||
|
||||
|
||||
class MatrixRtcConfig(Config):
|
||||
|
||||
@@ -17,8 +17,13 @@
|
||||
|
||||
"""Tests REST events for /rtc/endpoints path."""
|
||||
|
||||
import unittest as stdlib_unittest
|
||||
|
||||
from pydantic import ValidationError
|
||||
|
||||
from twisted.internet.testing import MemoryReactor
|
||||
|
||||
from synapse.config.matrixrtc import TransportConfigModel
|
||||
from synapse.rest import admin
|
||||
from synapse.rest.client import login, matrixrtc, register, room, versions
|
||||
from synapse.server import HomeServer
|
||||
@@ -30,7 +35,16 @@ from tests.unittest import HomeserverTestCase, override_config
|
||||
|
||||
PATH_PREFIX = "/_matrix/client/unstable/org.matrix.msc4143"
|
||||
RTC_ENDPOINT = {"type": "focusA", "required_field": "theField"}
|
||||
LIVEKIT_ENDPOINT = {
|
||||
LIVEKIT_TRANSPORT = {
|
||||
"type": "livekit",
|
||||
"url": "wss://livekit.example.com",
|
||||
}
|
||||
BACKWARDS_COMPATIBLE_LIVEKIT_TRANSPORT = {
|
||||
"type": "livekit",
|
||||
"url": "wss://livekit.example.com",
|
||||
"livekit_service_url": "https://livekit.example.com",
|
||||
}
|
||||
LEGACY_LIVEKIT_TRANSPORT = {
|
||||
"type": "livekit",
|
||||
"livekit_service_url": "https://livekit.example.com",
|
||||
}
|
||||
@@ -96,7 +110,7 @@ class MatrixRtcTestCase(HomeserverTestCase):
|
||||
@override_config(
|
||||
{
|
||||
"experimental_features": {"msc4143_enabled": True},
|
||||
"matrix_rtc": {"transports": [LIVEKIT_ENDPOINT]},
|
||||
"matrix_rtc": {"transports": [LIVEKIT_TRANSPORT]},
|
||||
}
|
||||
)
|
||||
def test_matrixrtc_endpoint_livekit_transport(self) -> None:
|
||||
@@ -104,7 +118,38 @@ class MatrixRtcTestCase(HomeserverTestCase):
|
||||
"GET", f"{PATH_PREFIX}/rtc/transports", access_token=self._alice_tok
|
||||
)
|
||||
self.assertEqual(200, channel.code, channel.json_body)
|
||||
self.assert_dict({"rtc_transports": [LIVEKIT_ENDPOINT]}, channel.json_body)
|
||||
self.assert_dict({"rtc_transports": [LIVEKIT_TRANSPORT]}, channel.json_body)
|
||||
|
||||
@override_config(
|
||||
{
|
||||
"experimental_features": {"msc4143_enabled": True},
|
||||
"matrix_rtc": {"transports": [BACKWARDS_COMPATIBLE_LIVEKIT_TRANSPORT]},
|
||||
}
|
||||
)
|
||||
def test_matrixrtc_endpoint_backwards_compatible_livekit_transport(self) -> None:
|
||||
channel = self.make_request(
|
||||
"GET", f"{PATH_PREFIX}/rtc/transports", access_token=self._alice_tok
|
||||
)
|
||||
self.assertEqual(200, channel.code, channel.json_body)
|
||||
self.assert_dict(
|
||||
{"rtc_transports": [BACKWARDS_COMPATIBLE_LIVEKIT_TRANSPORT]},
|
||||
channel.json_body,
|
||||
)
|
||||
|
||||
@override_config(
|
||||
{
|
||||
"experimental_features": {"msc4143_enabled": True},
|
||||
"matrix_rtc": {"transports": [LEGACY_LIVEKIT_TRANSPORT]},
|
||||
}
|
||||
)
|
||||
def test_matrixrtc_endpoint_legacy_livekit_transport(self) -> None:
|
||||
channel = self.make_request(
|
||||
"GET", f"{PATH_PREFIX}/rtc/transports", access_token=self._alice_tok
|
||||
)
|
||||
self.assertEqual(200, channel.code, channel.json_body)
|
||||
self.assert_dict(
|
||||
{"rtc_transports": [LEGACY_LIVEKIT_TRANSPORT]}, channel.json_body
|
||||
)
|
||||
|
||||
|
||||
class MatrixRtcVersionsTestCase(HomeserverTestCase):
|
||||
@@ -150,3 +195,23 @@ class MatrixRtcVersionsTestCase(HomeserverTestCase):
|
||||
channel = self.make_request("GET", "/_matrix/client/versions")
|
||||
self.assertEqual(channel.code, 200, channel.result)
|
||||
self.assertTrue(channel.json_body["unstable_features"]["org.matrix.msc4143"])
|
||||
|
||||
|
||||
class TransportConfigModelTestCase(stdlib_unittest.TestCase):
|
||||
"""Tests validation of the `TransportConfigModel` pydantic model."""
|
||||
|
||||
def test_livekit_transport_requires_url_or_livekit_service_url(self) -> None:
|
||||
with self.assertRaises(ValidationError):
|
||||
TransportConfigModel(type="livekit")
|
||||
|
||||
def test_livekit_transport_with_only_url(self) -> None:
|
||||
TransportConfigModel(type="livekit", url="wss://livekit.example.com")
|
||||
|
||||
def test_livekit_transport_with_only_livekit_service_url(self) -> None:
|
||||
TransportConfigModel(
|
||||
type="livekit", livekit_service_url="https://livekit.example.com"
|
||||
)
|
||||
|
||||
def test_invalid_field_type(self) -> None:
|
||||
with self.assertRaises(ValidationError):
|
||||
TransportConfigModel(type="livekit", url=1234) # type: ignore[arg-type]
|
||||
|
||||
Reference in New Issue
Block a user