77 lines
2.7 KiB
C#
77 lines
2.7 KiB
C#
using System;
|
|
using System.Globalization;
|
|
using System.Text.Json;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Jellyfin.Extensions.Json;
|
|
using MediaBrowser.Common.Extensions;
|
|
using MediaBrowser.Controller.Session;
|
|
using MediaBrowser.Model.Session;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace Emby.Server.Implementations.Session;
|
|
|
|
/// <summary>
|
|
/// Stands in for the websocket of a session another instance holds: messages are forwarded to that
|
|
/// instance, which writes them to the connection it owns and reports back whether it did.
|
|
/// </summary>
|
|
public sealed class RemoteSessionController : ISessionController
|
|
{
|
|
private readonly IPodMessageBus _bus;
|
|
private readonly ILogger _logger;
|
|
private readonly string _ownerPod;
|
|
private readonly string _sessionId;
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="RemoteSessionController"/> class.
|
|
/// </summary>
|
|
/// <param name="bus">The cross-instance bus.</param>
|
|
/// <param name="logger">The logger.</param>
|
|
/// <param name="ownerPod">The instance holding the connection.</param>
|
|
/// <param name="sessionId">The session identifier.</param>
|
|
/// <param name="supportsMediaControl">Whether the owner reported the session as controllable.</param>
|
|
public RemoteSessionController(IPodMessageBus bus, ILogger logger, string ownerPod, string sessionId, bool supportsMediaControl)
|
|
{
|
|
_bus = bus;
|
|
_logger = logger;
|
|
_ownerPod = ownerPod;
|
|
_sessionId = sessionId;
|
|
SupportsMediaControl = supportsMediaControl;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public bool IsSessionActive => true;
|
|
|
|
/// <inheritdoc />
|
|
public bool SupportsMediaControl { get; }
|
|
|
|
/// <inheritdoc />
|
|
public async Task SendMessage<T>(SessionMessageType name, Guid messageId, T data, CancellationToken cancellationToken)
|
|
{
|
|
var routed = new RoutedSessionMessage
|
|
{
|
|
SessionId = _sessionId,
|
|
MessageType = name,
|
|
MessageId = messageId,
|
|
Data = JsonSerializer.Serialize(data, JsonDefaults.Options)
|
|
};
|
|
|
|
var delivered = await _bus.RequestAsync(
|
|
_ownerPod,
|
|
new PodMessage
|
|
{
|
|
Kind = RoutedSessionMessage.Kind,
|
|
Payload = JsonSerializer.Serialize(routed, JsonDefaults.Options)
|
|
},
|
|
cancellationToken).ConfigureAwait(false);
|
|
|
|
if (!delivered)
|
|
{
|
|
_logger.LogWarning("Instance {OwnerPod} did not write the {MessageType} message for session {SessionId} to a connection.", _ownerPod, name, _sessionId);
|
|
|
|
throw new ResourceNotFoundException(
|
|
string.Format(CultureInfo.InvariantCulture, "No instance holds a connection to session {0}.", _sessionId));
|
|
}
|
|
}
|
|
}
|