You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Lidarr/src/Microsoft.AspNet.SignalR.Core/Infrastructure/ServerCommandHandler.cs

149 lines
4.1 KiB

// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.md in the project root for license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR.Json;
using Microsoft.AspNet.SignalR.Messaging;
namespace Microsoft.AspNet.SignalR.Infrastructure
{
/// <summary>
/// Default <see cref="IServerCommandHandler"/> implementation.
/// </summary>
internal class ServerCommandHandler : IServerCommandHandler, ISubscriber, IDisposable
{
private readonly IMessageBus _messageBus;
private readonly IServerIdManager _serverIdManager;
private readonly IJsonSerializer _serializer;
private IDisposable _subscription;
private const int MaxMessages = 10;
// The signal for all signalr servers
private const string ServerSignal = "__SIGNALR__SERVER__";
private static readonly string[] ServerSignals = new[] { ServerSignal };
public ServerCommandHandler(IDependencyResolver resolver) :
this(resolver.Resolve<IMessageBus>(),
resolver.Resolve<IServerIdManager>(),
resolver.Resolve<IJsonSerializer>())
{
}
public ServerCommandHandler(IMessageBus messageBus, IServerIdManager serverIdManager, IJsonSerializer serializer)
{
_messageBus = messageBus;
_serverIdManager = serverIdManager;
_serializer = serializer;
ProcessMessages();
}
public Action<ServerCommand> Command
{
get;
set;
}
public IList<string> EventKeys
{
get
{
return ServerSignals;
}
}
event Action<ISubscriber, string> ISubscriber.EventKeyAdded
{
add
{
}
remove
{
}
}
event Action<ISubscriber, string> ISubscriber.EventKeyRemoved
{
add
{
}
remove
{
}
}
public Action<TextWriter> WriteCursor { get; set; }
public string Identity
{
get
{
return _serverIdManager.ServerId;
}
}
public Subscription Subscription
{
get;
set;
}
public Task SendCommand(ServerCommand command)
{
// Store where the message originated from
command.ServerId = _serverIdManager.ServerId;
// Send the command to the all servers
return _messageBus.Publish(_serverIdManager.ServerId, ServerSignal, _serializer.Stringify(command));
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (_subscription != null)
{
_subscription.Dispose();
}
}
}
public void Dispose()
{
Dispose(true);
}
private void ProcessMessages()
{
// Process messages that come from the bus for servers
_subscription = _messageBus.Subscribe(this, cursor: null, callback: HandleServerCommands, maxMessages: MaxMessages, state: null);
}
private Task<bool> HandleServerCommands(MessageResult result, object state)
{
result.Messages.Enumerate<object>(m => ServerSignal.Equals(m.Key),
(s, m) =>
{
var command = _serializer.Parse<ServerCommand>(m.Value, m.Encoding);
OnCommand(command);
},
state: null);
return TaskAsyncHelper.True;
}
private void OnCommand(ServerCommand command)
{
if (Command != null)
{
Command(command);
}
}
}
}