2019-06-03 14:57:05 +00:00
|
|
|
using System;
|
2019-07-05 21:37:10 +00:00
|
|
|
using System.Collections.ObjectModel;
|
2019-07-07 21:12:13 +00:00
|
|
|
using System.Threading.Tasks;
|
|
|
|
using System.Threading;
|
2019-07-10 21:17:10 +00:00
|
|
|
using System.Linq.Expressions;
|
|
|
|
using System.Linq;
|
2019-07-06 19:52:28 +00:00
|
|
|
using Grpc.Core;
|
2019-07-07 21:12:13 +00:00
|
|
|
using wellKnown = Google.Protobuf.WellKnownTypes;
|
|
|
|
using Aurora.Proto.General;
|
|
|
|
using Aurora.Proto.Party;
|
|
|
|
using Aurora.Proto.Playback;
|
|
|
|
using Aurora.Proto.Events;
|
2019-07-06 19:52:28 +00:00
|
|
|
using Aurora.Services;
|
2019-07-05 18:17:09 +00:00
|
|
|
namespace Aurora.Executors
|
2019-06-03 14:57:05 +00:00
|
|
|
{
|
2019-07-05 15:37:44 +00:00
|
|
|
public class ClientExecutor : BaseExecutor
|
2019-06-03 14:57:05 +00:00
|
|
|
{
|
2019-07-06 19:52:28 +00:00
|
|
|
private Channel _channel;
|
|
|
|
private RemotePartyService.RemotePartyServiceClient _remotePartyClient;
|
|
|
|
private RemotePlaybackService.RemotePlaybackServiceClient _remotePlaybackClient;
|
2019-07-07 21:12:13 +00:00
|
|
|
private RemoteEventService.RemoteEventServiceClient _remoteEventsClient;
|
|
|
|
private Task _eventsTask;
|
2019-07-10 21:17:10 +00:00
|
|
|
CancellationTokenSource _eventCancellationTokenSource;
|
2019-07-06 19:52:28 +00:00
|
|
|
|
|
|
|
private ObservableCollection<PartyMember> _partyMembers;
|
|
|
|
|
2019-07-05 15:37:44 +00:00
|
|
|
public ClientExecutor()
|
2019-06-03 14:57:05 +00:00
|
|
|
{
|
2019-07-06 19:52:28 +00:00
|
|
|
_partyMembers = new ObservableCollection<PartyMember>();
|
2019-06-03 14:57:05 +00:00
|
|
|
}
|
|
|
|
|
2019-07-05 21:37:10 +00:00
|
|
|
#region Properties
|
|
|
|
public override ObservableCollection<PartyMember> PartyMembers
|
|
|
|
{
|
2019-07-06 19:52:28 +00:00
|
|
|
get { return _partyMembers; }
|
2019-07-05 21:37:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endregion Properties
|
|
|
|
|
2019-07-07 21:12:13 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Initiates the connection to a party.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="hostname">The hostname of the gRPC server</param>
|
2019-07-06 19:52:28 +00:00
|
|
|
public override void Connect(string hostname)
|
2019-06-03 14:57:05 +00:00
|
|
|
{
|
2019-07-06 19:52:28 +00:00
|
|
|
_channel = new Channel(string.Format("{0}:{1}", hostname, SettingsService.Instance.DefaultPort), ChannelCredentials.Insecure);
|
|
|
|
|
|
|
|
_remotePartyClient = new RemotePartyService.RemotePartyServiceClient(_channel);
|
|
|
|
_remotePlaybackClient = new RemotePlaybackService.RemotePlaybackServiceClient(_channel);
|
2019-07-07 21:12:13 +00:00
|
|
|
_remoteEventsClient = new RemoteEventService.RemoteEventServiceClient(_channel);
|
|
|
|
|
|
|
|
//Assign but don't start task
|
|
|
|
_eventsTask = new Task(GetEvents);
|
2019-07-10 21:17:10 +00:00
|
|
|
_eventCancellationTokenSource = new CancellationTokenSource();
|
2019-07-06 19:52:28 +00:00
|
|
|
|
|
|
|
JoinParty();
|
2019-06-03 14:57:05 +00:00
|
|
|
}
|
|
|
|
|
2019-07-07 21:12:13 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Shutdown Connections
|
|
|
|
/// </summary>
|
|
|
|
/// <returns></returns>
|
2019-07-06 19:52:28 +00:00
|
|
|
public override async void Close()
|
2019-06-03 14:57:05 +00:00
|
|
|
{
|
2019-07-10 21:17:10 +00:00
|
|
|
_eventCancellationTokenSource.Cancel();
|
2019-07-06 19:52:28 +00:00
|
|
|
await _channel.ShutdownAsync();
|
2019-06-03 14:57:05 +00:00
|
|
|
}
|
|
|
|
|
2019-07-06 19:52:28 +00:00
|
|
|
public override void AddToQueue()
|
2019-06-03 14:57:05 +00:00
|
|
|
{
|
|
|
|
throw new NotImplementedException();
|
|
|
|
}
|
|
|
|
|
2019-07-06 19:52:28 +00:00
|
|
|
public override ObservableCollection<PartyMember> GetMembers()
|
2019-06-03 14:57:05 +00:00
|
|
|
{
|
|
|
|
throw new NotImplementedException();
|
|
|
|
}
|
|
|
|
|
2019-07-06 19:52:28 +00:00
|
|
|
public override void GetQueue()
|
2019-06-03 14:57:05 +00:00
|
|
|
{
|
|
|
|
throw new NotImplementedException();
|
|
|
|
}
|
|
|
|
|
|
|
|
public override void RemoveFromQueue()
|
|
|
|
{
|
|
|
|
throw new NotImplementedException();
|
|
|
|
}
|
|
|
|
|
2019-07-10 21:17:10 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Join the remote party.
|
|
|
|
/// </summary>
|
|
|
|
/// <returns></returns>
|
2019-07-06 19:52:28 +00:00
|
|
|
private async void JoinParty()
|
2019-06-03 14:57:05 +00:00
|
|
|
{
|
2019-07-06 19:52:28 +00:00
|
|
|
await _remotePartyClient.JoinPartyAsync(new JoinPartyRequest
|
|
|
|
{
|
|
|
|
UserName = SettingsService.Instance.Username,
|
|
|
|
});
|
|
|
|
|
2019-07-07 21:12:13 +00:00
|
|
|
RefreshMembers();
|
|
|
|
|
|
|
|
//Subscribe to events
|
|
|
|
SubscribeRequest req = new SubscribeRequest();
|
|
|
|
req.EventTypes.Add(EventType.PartyMemberJoined);
|
|
|
|
req.EventTypes.Add(EventType.PartyMemberLeft);
|
|
|
|
try
|
|
|
|
{
|
|
|
|
_remoteEventsClient.SubscribeToEvents(req);
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
Console.WriteLine("Error subscribing to events: " + ex.Message);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_eventsTask.Start();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-07-10 21:17:10 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Refresh members list.
|
|
|
|
/// </summary>
|
2019-07-07 21:12:13 +00:00
|
|
|
private void RefreshMembers()
|
|
|
|
{
|
2019-07-06 19:52:28 +00:00
|
|
|
MembersResponse resposne = _remotePartyClient.GetPartyMembers(new Empty());
|
|
|
|
//Add members
|
|
|
|
foreach (PartyMember member in resposne.Members)
|
|
|
|
{
|
|
|
|
_partyMembers.Add(member);
|
|
|
|
}
|
|
|
|
|
|
|
|
//Remove out of date members
|
|
|
|
foreach (PartyMember member in _partyMembers)
|
|
|
|
{
|
|
|
|
if (!resposne.Members.Contains(member))
|
|
|
|
{
|
|
|
|
_partyMembers.Remove(member);
|
|
|
|
}
|
|
|
|
}
|
2019-06-03 14:57:05 +00:00
|
|
|
}
|
2019-07-07 21:12:13 +00:00
|
|
|
|
2019-07-10 21:17:10 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Asynchronous function for processing events off of the event stream.
|
|
|
|
/// </summary>
|
|
|
|
/// <returns></returns>
|
2019-07-07 21:12:13 +00:00
|
|
|
private async void GetEvents()
|
|
|
|
{
|
|
|
|
using (AsyncServerStreamingCall<BaseEvent> eventStream = _remoteEventsClient.GetEvents(new Empty()))
|
|
|
|
{
|
2019-07-10 21:17:10 +00:00
|
|
|
while (!_eventCancellationTokenSource.Token.IsCancellationRequested)
|
2019-07-07 21:12:13 +00:00
|
|
|
{
|
2019-07-10 21:17:10 +00:00
|
|
|
if (await eventStream.ResponseStream.MoveNext(_eventCancellationTokenSource.Token))
|
2019-07-07 21:12:13 +00:00
|
|
|
{
|
2019-07-10 21:17:10 +00:00
|
|
|
//Convert derived event type
|
|
|
|
BaseEvent e = eventStream.ResponseStream.Current;
|
|
|
|
switch (e.DerivedEventCase)
|
|
|
|
{
|
|
|
|
case BaseEvent.DerivedEventOneofCase.None:
|
|
|
|
{
|
|
|
|
throw new InvalidOperationException();
|
|
|
|
}
|
|
|
|
case BaseEvent.DerivedEventOneofCase.PartyMemberJoinedEvent:
|
|
|
|
{
|
|
|
|
PartyMemberJoinedEvent derivedEvent = e.PartyMemberJoinedEvent;
|
|
|
|
_partyMembers.Add(derivedEvent.Member);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case BaseEvent.DerivedEventOneofCase.PartyMemberLeftEvent:
|
|
|
|
{
|
|
|
|
PartyMemberJoinedEvent derivedEvent = e.PartyMemberJoinedEvent;
|
|
|
|
var found = _partyMembers.Where(x => x.Id == derivedEvent.Member.Id);
|
|
|
|
foreach (PartyMember member in found)
|
|
|
|
{
|
|
|
|
_partyMembers.Remove(member);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2019-07-07 21:12:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-06-03 14:57:05 +00:00
|
|
|
}
|
|
|
|
}
|