Removed old proto definitions (not tested)

This commit is contained in:
watsonb8 2020-02-02 16:49:01 -05:00
parent 2a7e10364e
commit 51ab2d9c42
48 changed files with 581 additions and 1645 deletions

View File

@ -1,8 +1,8 @@
using NUnit.Framework; using NUnit.Framework;
using Aurora.Proto.PartyV2; using Aurora.Proto.Party;
using Aurora.Services.Server; using Aurora.Services.Server;
using Aurora.Services.Server.EventManager; using Aurora.Services.EventManager;
using Grpc.Core; using Grpc.Core;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Threading; using System.Threading;

View File

@ -1,5 +1,5 @@
using NUnit.Framework; using NUnit.Framework;
using Aurora.Proto.PartyV2; using Aurora.Proto.Party;
using Aurora.Services.Server; using Aurora.Services.Server;
using Grpc.Core; using Grpc.Core;
using System.Threading.Tasks; using System.Threading.Tasks;

View File

@ -1,5 +1,5 @@
using NUnit.Framework; using NUnit.Framework;
using Aurora.Proto.PartyV2; using Aurora.Proto.Party;
using Aurora.Services.Server; using Aurora.Services.Server;
using Grpc.Core; using Grpc.Core;
using System.Threading.Tasks; using System.Threading.Tasks;

View File

@ -1,6 +1,6 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using NUnit.Framework; using NUnit.Framework;
using Aurora.Proto.PartyV2; using Aurora.Proto.Party;
using Aurora.Services.Server; using Aurora.Services.Server;
using Grpc.Core; using Grpc.Core;
using Autofac; using Autofac;

View File

@ -1,9 +1,9 @@
using Autofac; using Autofac;
using Aurora.Proto.PartyV2; using Aurora.Proto.Party;
using Aurora.Services.Server; using Aurora.Services.Server;
using Aurora.Services.Library; using Aurora.Services.Library;
using Aurora.Services.Settings; using Aurora.Services.Settings;
using Aurora.Services.Server.EventManager; using Aurora.Services.EventManager;
using Aurora.test.Models.Mock; using Aurora.test.Models.Mock;
using System.IO; using System.IO;
using Grpc.Core; using Grpc.Core;

View File

@ -28,7 +28,7 @@ namespace Aurora.test.Models.Mock
/// The current sessions clientId. This is assigned by the server. This is not persisted. /// The current sessions clientId. This is assigned by the server. This is not persisted.
/// </summary> /// </summary>
/// <value></value> /// <value></value>
public string ClientId { get; set; } public string ClientName { get; set; }
public string LibraryLocation { get; set; } public string LibraryLocation { get; set; }
} }

View File

@ -6,8 +6,7 @@ using Aurora.Design.Views.Party;
using Aurora.Design.Views.Profile; using Aurora.Design.Views.Profile;
using Aurora.Design.Views.Songs; using Aurora.Design.Views.Songs;
using Aurora.Design.Views.Stations; using Aurora.Design.Views.Stations;
using Aurora.Services.ClientService; using Aurora.Services.EventManager;
using Aurora.Services.Server.EventManager;
using Autofac; using Autofac;
using LibVLCSharp.Shared; using LibVLCSharp.Shared;
using Xamarin.Forms; using Xamarin.Forms;
@ -30,7 +29,6 @@ namespace Aurora
// _builder.RegisterInstance<IPlayer>(new PlayerService()).SingleInstance(); // _builder.RegisterInstance<IPlayer>(new PlayerService()).SingleInstance();
_builder.RegisterType<PlayerService>().As<IPlayer>().SingleInstance(); _builder.RegisterType<PlayerService>().As<IPlayer>().SingleInstance();
_builder.RegisterType<SettingsService>().As<ISettingsService>().SingleInstance(); _builder.RegisterType<SettingsService>().As<ISettingsService>().SingleInstance();
_builder.RegisterType<ClientService>().As<IClientService>().SingleInstance();
_builder.RegisterType<LibraryService>().As<ILibraryService>().SingleInstance(); _builder.RegisterType<LibraryService>().As<ILibraryService>().SingleInstance();
_builder.RegisterType<EventManager>().As<IEventManager>().SingleInstance(); _builder.RegisterType<EventManager>().As<IEventManager>().SingleInstance();
_builder.RegisterType<MainView>().SingleInstance(); _builder.RegisterType<MainView>().SingleInstance();

View File

@ -62,10 +62,6 @@
<ItemGroup> <ItemGroup>
<Protobuf Include="Proto\general.proto" /> <Protobuf Include="Proto\general.proto" />
<Protobuf Include="Proto\party.proto" /> <Protobuf Include="Proto\party.proto" />
<Protobuf Include="Proto\events.proto" />
<Protobuf Include="Proto\playback.proto" />
<Protobuf Include="Proto\sync.proto" />
<Protobuf Include="Proto\party.v2.proto" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Resources\backward.png" /> <EmbeddedResource Include="Resources\backward.png" />

View File

@ -24,7 +24,7 @@ namespace Aurora.Design.Components.MemberList
/// <returns></returns> /// <returns></returns>
public static readonly BindableProperty MembersProperty = public static readonly BindableProperty MembersProperty =
BindableProperty.Create(propertyName: "Members", BindableProperty.Create(propertyName: "Members",
returnType: typeof(ObservableCollection<PartyMember>), returnType: typeof(ObservableCollection<Member>),
declaringType: typeof(MemberList), declaringType: typeof(MemberList),
defaultBindingMode: BindingMode.Default, defaultBindingMode: BindingMode.Default,
propertyChanged: OnMembersChanged); propertyChanged: OnMembersChanged);
@ -33,11 +33,11 @@ namespace Aurora.Design.Components.MemberList
/// Backing property for MembersProperty /// Backing property for MembersProperty
/// </summary> /// </summary>
/// <value></value> /// <value></value>
public ObservableCollection<PartyMember> Members public ObservableCollection<Member> Members
{ {
get get
{ {
return (ObservableCollection<PartyMember>)GetValue(MembersProperty); return (ObservableCollection<Member>)GetValue(MembersProperty);
} }
set set
{ {

View File

@ -1,19 +1,18 @@
using System; using System;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Threading;
using System.Linq; using System.Linq;
using Xamarin.Forms; using Xamarin.Forms;
using Aurora.Services;
using Aurora.Proto.General;
using Aurora.Proto.Party; using Aurora.Proto.Party;
using Aurora.Proto.Events;
using Aurora.Services.ClientService;
using Aurora.Services.ClientService.Events;
using Aurora.Services.Player;
using Aurora.Services.EventManager;
using Aurora.Models.Media; using Aurora.Models.Media;
using Aurora.Services.Client;
using Aurora.Design.Views.Party.NewPartyDialog; using Aurora.Design.Views.Party.NewPartyDialog;
using Aurora.Services.Settings; using Aurora.Services.Settings;
using Aurora.Services.Server;
using Aurora.Services.EventManager;
using Grpc.Core;
namespace Aurora.Design.Views.Party namespace Aurora.Design.Views.Party
{ {
@ -25,25 +24,37 @@ namespace Aurora.Design.Views.Party
Hosting, Hosting,
Connecting, Connecting,
} }
public delegate void EventHandler(BaseEvent e);
public class PartyViewModel : BaseViewModel public class PartyViewModel : BaseViewModel
{ {
private PartyState _state; private PartyState _state;
private string _hostname = ""; private string _hostname = "";
private ObservableCollection<PartyMember> _members; private ObservableCollection<Member> _members;
private ObservableCollection<BaseMedia> _queue; private ObservableCollection<BaseMedia> _queue;
private BaseMedia _selectedMedia; private BaseMedia _selectedMedia;
private IClientService _client; // private IClientService _client;
private ISettingsService _settingsService; private ISettingsService _settingsService;
private IClientService _clientService;
private IServerService _serverService;
private IEventManager _eventManager;
private CancellationTokenSource _eventCancellationTokenSource;
private Dictionary<BaseEvent.DerivedEventOneofCase, EventHandler> _eventHandlers;
private int _selectedTabIndex; private int _selectedTabIndex;
public PartyViewModel(ISettingsService settingsService, IClientService clientService) public PartyViewModel(
ISettingsService settingsService,
IServerService serverService,
IEventManager eventManager)
{ {
_members = new ObservableCollection<PartyMember>(); _members = new ObservableCollection<Member>();
_queue = new ObservableCollection<BaseMedia>(); _queue = new ObservableCollection<BaseMedia>();
this._settingsService = settingsService; this._settingsService = settingsService;
this._serverService = serverService;
this._eventManager = eventManager;
SetState(PartyState.SelectingHost); SetState(PartyState.SelectingHost);
@ -51,19 +62,15 @@ namespace Aurora.Design.Views.Party
LeavePartyCommand = new Command(OnLeavePartyCommandExecute, CanLeavePartyCommandExecute); LeavePartyCommand = new Command(OnLeavePartyCommandExecute, CanLeavePartyCommandExecute);
_client = clientService; //Setup event handlers
_eventHandlers = new Dictionary<BaseEvent.DerivedEventOneofCase, EventHandler>()
_client.OnMediaPaused += this.OnRemoteMediaPaused; {
_client.OnMediaResumed += this.OnRemoteMediaResumed; {BaseEvent.DerivedEventOneofCase.MediaPausedEvent, this.OnRemoteMediaPaused},
_client.OnNewMediaPlaying += this.OnNewRemoteMediaPlaying; {BaseEvent.DerivedEventOneofCase.MediaResumedEvent, this.OnRemoteMediaResumed},
_client.OnPartyMemberJoined += this.OnPartyMemberJoined; {BaseEvent.DerivedEventOneofCase.NewMediaPlayingEvent, this.OnNewRemoteMediaPlaying},
_client.OnPartyMemberLeft += this.OnPartyMemberLeft; {BaseEvent.DerivedEventOneofCase.MemberCreatedEvent, this.OnPartyMemberJoined},
{BaseEvent.DerivedEventOneofCase.MemberDeletedEvent, this.OnPartyMemberLeft}
} };
~PartyViewModel()
{
//Task.Run(ServerService.Instance.Stop);
} }
#region Properties #region Properties
@ -78,7 +85,7 @@ namespace Aurora.Design.Views.Party
/// Publc property for the members list /// Publc property for the members list
/// </summary> /// </summary>
/// <value></value> /// <value></value>
public ObservableCollection<PartyMember> Members public ObservableCollection<Member> Members
{ {
get get
{ {
@ -140,7 +147,7 @@ namespace Aurora.Design.Views.Party
if (this._state == PartyState.Hosting || if (this._state == PartyState.Hosting ||
this._state == PartyState.InParty) this._state == PartyState.InParty)
{ {
await _client.GetEvents().ConfigureAwait(false); await this.GetEvents().ConfigureAwait(false);
} }
else else
{ {
@ -177,7 +184,7 @@ namespace Aurora.Design.Views.Party
/// <returns></returns> /// <returns></returns>
public override Task OnInactive() public override Task OnInactive()
{ {
_client.StopEvents(); this._eventCancellationTokenSource.Cancel();
return Task.FromResult<object>(null); return Task.FromResult<object>(null);
} }
@ -186,7 +193,7 @@ namespace Aurora.Design.Views.Party
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="args"></param> /// <param name="args"></param>
public void OnRemoteMediaPaused(object sender, MediaPausedEventArgs args) public void OnRemoteMediaPaused(BaseEvent e)
{ {
StopPlaying(); StopPlaying();
} }
@ -196,9 +203,9 @@ namespace Aurora.Design.Views.Party
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="args"></param> /// <param name="args"></param>
public void OnNewRemoteMediaPlaying(object sender, NewMediaPlayingEventArgs args) public void OnNewRemoteMediaPlaying(BaseEvent e)
{ {
PlayFromBeginning(GetMediaFromQueue(args.Event.Media.Id)); PlayFromBeginning(GetMediaFromQueue(e.NewMediaPlayingEvent.Media.Name));
} }
/// <summary> /// <summary>
@ -206,7 +213,7 @@ namespace Aurora.Design.Views.Party
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="args"></param> /// <param name="args"></param>
public void OnRemoteMediaResumed(object sender, MediaResumedEventArgs args) public void OnRemoteMediaResumed(BaseEvent e)
{ {
PlayResume(); PlayResume();
} }
@ -216,17 +223,9 @@ namespace Aurora.Design.Views.Party
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="args"></param> /// <param name="args"></param>
public void OnPartyMemberJoined(object sender, PartyMemberJoinedEventArgs args) public void OnPartyMemberJoined(BaseEvent e)
{ {
PartyMember member = new PartyMember Members.Add(e.MemberCreatedEvent.Member);
{
UserName = args.Event.Member.UserName,
Id = args.Event.Member.Id,
IpAddress = args.Event.Member.IpAddress,
Port = args.Event.Member.Port
};
Members.Add(member);
} }
/// <summary> /// <summary>
@ -234,10 +233,10 @@ namespace Aurora.Design.Views.Party
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="args"></param> /// <param name="args"></param>
public void OnPartyMemberLeft(object sender, PartyMemberLeftEventArgs args) public void OnPartyMemberLeft(BaseEvent e)
{ {
var found = Members.Where(x => x.Id == args.Event.Member.Id); var found = Members.Where(x => x.Name == e.MemberDeletedEvent.MemberName);
foreach (PartyMember member in found) foreach (Member member in found)
{ {
_members.Remove(member); _members.Remove(member);
} }
@ -249,14 +248,14 @@ namespace Aurora.Design.Views.Party
private async void OnJoinCommandExecute() private async void OnJoinCommandExecute()
{ {
SetState(PartyState.Connecting); SetState(PartyState.Connecting);
_client.Start(_hostname, this._settingsService.DefaultPort.ToString()); _clientService.Start(_hostname, this._settingsService.DefaultPort.ToString());
await JoinParty(false); await JoinParty(false);
//TODO add cancellation token //TODO add cancellation token
try try
{ {
SetState(PartyState.InParty); SetState(PartyState.InParty);
await _client.GetEvents().ConfigureAwait(true); await GetEvents().ConfigureAwait(true);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -273,10 +272,9 @@ namespace Aurora.Design.Views.Party
{ {
//Change state //Change state
SetState(PartyState.Connecting); SetState(PartyState.Connecting);
ServerService.Instance.Start(); _serverService.Start("test", "asdf");
string localHost = ServerService.GetLocalIPAddress(); string localHost = ServerService.GetLocalIPAddress();
_client.IsHost = true; _clientService.Start(localHost, this._settingsService.DefaultPort.ToString());
_client.Start(localHost, this._settingsService.DefaultPort.ToString());
await JoinParty(true); await JoinParty(true);
@ -284,7 +282,7 @@ namespace Aurora.Design.Views.Party
try try
{ {
SetState(PartyState.Hosting); SetState(PartyState.Hosting);
await _client.GetEvents().ConfigureAwait(true); // await _clientService.RemotePartyServiceClient.GetEvents().ConfigureAwait(true);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -299,7 +297,10 @@ namespace Aurora.Design.Views.Party
private async void OnLeavePartyCommandExecute() private async void OnLeavePartyCommandExecute()
{ {
await _client.RemotePartyClient.LeavePartyAsync(new LeavePartyRequest()); await _clientService.RemotePartyServiceClient.DeleteMemberAsync(new DeleteMemberRequest()
{
Name = _settingsService.ClientName
});
} }
private bool CanLeavePartyCommandExecute() private bool CanLeavePartyCommandExecute()
@ -315,7 +316,7 @@ namespace Aurora.Design.Views.Party
AudioMetadata meta = _selectedMedia.Metadata as AudioMetadata; AudioMetadata meta = _selectedMedia.Metadata as AudioMetadata;
MediaPausedEvent mediaPaused = new MediaPausedEvent(); MediaPausedEvent mediaPaused = new MediaPausedEvent();
EventManager.Instance.FireEvent(new BaseEvent() _eventManager.FireEvent(new BaseEvent()
{ {
MediaPausedEvent = mediaPaused MediaPausedEvent = mediaPaused
}); });
@ -326,7 +327,7 @@ namespace Aurora.Design.Views.Party
AudioMetadata meta = _selectedMedia.Metadata as AudioMetadata; AudioMetadata meta = _selectedMedia.Metadata as AudioMetadata;
MediaResumedEvent mediaResumed = new MediaResumedEvent(); MediaResumedEvent mediaResumed = new MediaResumedEvent();
EventManager.Instance.FireEvent(new BaseEvent() _eventManager.FireEvent(new BaseEvent()
{ {
MediaResumedEvent = mediaResumed MediaResumedEvent = mediaResumed
}); });
@ -357,16 +358,17 @@ namespace Aurora.Design.Views.Party
AudioMetadata meta = _selectedMedia.Metadata as AudioMetadata; AudioMetadata meta = _selectedMedia.Metadata as AudioMetadata;
NewMediaPlayingEvent mediaPlaying = new NewMediaPlayingEvent() NewMediaPlayingEvent mediaPlaying = new NewMediaPlayingEvent()
{ {
Media = new RemoteMediaData() Media = new Media()
{ {
Id = _selectedMedia.Id, //TODO need full resource name
Name = _selectedMedia.Id,
Title = meta.Title, Title = meta.Title,
Artist = meta.Artist, Artist = meta.Artist,
Album = meta.Album, Album = meta.Album,
} }
}; };
EventManager.Instance.FireEvent(new BaseEvent() _eventManager.FireEvent(new BaseEvent()
{ {
NewMediaPlayingEvent = mediaPlaying NewMediaPlayingEvent = mediaPlaying
}); });
@ -389,24 +391,31 @@ namespace Aurora.Design.Views.Party
{ {
try try
{ {
JoinPartyResponse resp = await _client.RemotePartyClient.JoinPartyAsync(new JoinPartyRequest Member resp = await _clientService.RemotePartyServiceClient.CreateMemberAsync(new CreateMemberRequest
{ {
UserName = this._settingsService.Username, Member = new Member()
{
UserName = this._settingsService.Username,
}
}); });
this._settingsService.ClientId = resp.ClientId; this._settingsService.ClientName = resp.Name;
RefreshMembers(); await RefreshMembers();
//Subscribe to events //Subscribe to events
await SubscribeToEvents(); await SubscribeToEvents();
Queue.Clear(); Queue.Clear();
QueueResponse queueResponse = _client.RemotePartyClient.GetQueue(new Empty());
ListMediaResponse mediaResponse = await _clientService.RemotePartyServiceClient.ListMediaAsync(new ListMediaRequest()
{
PageSize = 50,
Parent = "TODO"
});
//Convert received data to remote audio models //Convert received data to remote audio models
foreach (RemoteMediaData data in queueResponse.MediaList) foreach (Media data in mediaResponse.Media)
{ {
//Assign received metadata (since this can't be aquired from a file) //Assign received metadata (since this can't be aquired from a file)
AudioMetadata meta = new AudioMetadata(); AudioMetadata meta = new AudioMetadata();
@ -415,11 +424,10 @@ namespace Aurora.Design.Views.Party
meta.Artist = data.Artist; meta.Artist = data.Artist;
meta.Duration = data.Duration; meta.Duration = data.Duration;
RemoteAudio remote = new RemoteAudio(data.Id, RemoteAudio remote = new RemoteAudio(data.Name,
asHost, asHost,
meta, meta,
_client.RemotePlaybackClient, _clientService.RemotePartyServiceClient);
_client.RemoteSyncClient);
Queue.Add(remote); Queue.Add(remote);
OnPropertyChanged("Queue"); OnPropertyChanged("Queue");
@ -434,47 +442,52 @@ namespace Aurora.Design.Views.Party
private async Task LeaveParty() private async Task LeaveParty()
{ {
//Stop receiving events //Stop receiving events
_client.StopEvents(); // _client.StopEvents();
//Unsubscribe //Unsubscribe
await UnsubscribeFromEvents(); await UnsubscribeFromEvents();
//Leave party //Leave party
LeavePartyRequest leaveReq = new LeavePartyRequest(); DeleteMemberRequest req = new DeleteMemberRequest()
await _client.RemotePartyClient.LeavePartyAsync(leaveReq); {
Name = _settingsService.ClientName
};
await _clientService.RemotePartyServiceClient.DeleteMemberAsync(req);
} }
private async Task SubscribeToEvents() private async Task SubscribeToEvents()
{ {
SubscribeRequest req = new SubscribeRequest(); CreateEventSubscriptionListRequest req = new CreateEventSubscriptionListRequest();
req.EventTypes.Add(EventType.PartyMemberJoined); req.Parent = this._settingsService.ClientName;
req.EventTypes.Add(EventType.PartyMemberLeft); req.EventSubscriptions.Add(new EventSubscription() { Type = EventType.MemberCreated });
req.EventTypes.Add(EventType.MediaPlaying); req.EventSubscriptions.Add(new EventSubscription() { Type = EventType.MemberDeleted });
req.EventTypes.Add(EventType.MediaStopped); req.EventSubscriptions.Add(new EventSubscription() { Type = EventType.MediaPlaying });
if (!string.IsNullOrWhiteSpace(this._settingsService.ClientId)) req.EventSubscriptions.Add(new EventSubscription() { Type = EventType.MediaStopped });
{
req.ClientId = this._settingsService.ClientId;
}
Console.WriteLine(string.Format("CLIENT {0} - SubscribeToEvents called from client with id", this._settingsService.ClientName));
Console.WriteLine(string.Format("CLIENT {0} - SubscribeToEvents called from client with id", this._settingsService.ClientId)); await _clientService.RemotePartyServiceClient.CreateEventSubscriptionListAsync(req);
await _client.RemoteEventClient.SubscribeToEventsAsync(req);
} }
private async Task UnsubscribeFromEvents() private async Task UnsubscribeFromEvents()
{ {
UnsubscribeAllRequest unsubscribeReq = new UnsubscribeAllRequest(); DeleteAllEventSubscriptionsRequest unsubscribeReq = new DeleteAllEventSubscriptionsRequest();
await _client.RemoteEventClient.UnsubscribeFromAllAsync(unsubscribeReq); await _clientService.RemotePartyServiceClient.DeleteAllEventSubscriptionsAsync(unsubscribeReq);
} }
/// <summary> /// <summary>
/// Refresh members list. /// Refresh members list.
/// </summary> /// </summary>
private void RefreshMembers() private async Task RefreshMembers()
{ {
Members.Clear(); Members.Clear();
MembersResponse response = _client.RemotePartyClient.GetPartyMembers(new Empty()); ListMembersResponse response = await _clientService.RemotePartyServiceClient.ListMembersAsync(
new ListMembersRequest()
{
Parent = "TODO",
PageSize = 50,
});
//Add members //Add members
foreach (PartyMember member in response.Members) foreach (Member member in response.Members)
{ {
Members.Add(member); Members.Add(member);
} }
@ -514,6 +527,47 @@ namespace Aurora.Design.Views.Party
base.ChangePlayerState(null, Main.PlayAction.Pause); base.ChangePlayerState(null, Main.PlayAction.Pause);
} }
/// <summary>
/// Asynchronous function for processing events off of the event stream.
/// </summary>
/// <returns></returns>
public async Task GetEvents()
{
_eventCancellationTokenSource = new CancellationTokenSource();
string clientName = this._settingsService.ClientName;
Console.WriteLine(string.Format("CLIENT {0} - GetEvents called from client with id", clientName));
using (AsyncServerStreamingCall<BaseEvent> eventStream = _clientService.RemotePartyServiceClient
.GetEvents(new GetEventsRequest { Parent = this._settingsService.ClientName }))
{
try
{
while (!_eventCancellationTokenSource.Token.IsCancellationRequested &&
await eventStream.ResponseStream.MoveNext(_eventCancellationTokenSource.Token))
{
try
{
BaseEvent e = new BaseEvent(eventStream.ResponseStream.Current);
_eventHandlers.TryGetValue(e.DerivedEventCase, out EventHandler handler);
if (handler != null && handler != null)
{
handler.Invoke(e);
}
}
catch (Exception ex)
{
Console.WriteLine("Exception while parsing event ---" + ex.Message);
}
}
}
catch (Exception ex)
{
Console.WriteLine(string.Format("EXCEPTION while parsing events --- " + ex.Message));
}
}
}
#endregion Private Methods #endregion Private Methods
} }
} }

View File

@ -3,27 +3,23 @@ using System.IO;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Aurora.Proto.General; using Aurora.Proto.General;
using Aurora.Proto.Playback; using Aurora.Proto.Party;
using Aurora.Proto.Sync;
namespace Aurora.Models.Media namespace Aurora.Models.Media
{ {
public class RemoteAudio : BaseMedia public class RemoteAudio : BaseMedia
{ {
private RemotePlaybackService.RemotePlaybackServiceClient _remotePlaybackClient; private RemotePartyService.RemotePartyServiceClient _remotePartyService;
private RemoteSyncService.RemoteSyncServiceClient _remoteSyncClient;
private CancellationTokenSource _cancellationTokenSource; private CancellationTokenSource _cancellationTokenSource;
#region Constructor #region Constructor
public RemoteAudio(string id, public RemoteAudio(string id,
bool fromHost, bool fromHost,
AudioMetadata metadata, AudioMetadata metadata,
RemotePlaybackService.RemotePlaybackServiceClient playbackClient, RemotePartyService.RemotePartyServiceClient partyClient)
RemoteSyncService.RemoteSyncServiceClient syncClient)
{ {
this.Id = id; this.Id = id;
this._remotePlaybackClient = playbackClient; this._remotePartyService = partyClient;
this._remoteSyncClient = syncClient;
this.Metadata = metadata; this.Metadata = metadata;
this.FromHost = fromHost; this.FromHost = fromHost;
@ -41,11 +37,11 @@ namespace Aurora.Models.Media
get { return MediaTypeEnum.Audio; } get { return MediaTypeEnum.Audio; }
} }
public RemoteSyncService.RemoteSyncServiceClient RemoteSyncClient public RemotePartyService.RemotePartyServiceClient RemotePartyServiceClient
{ {
get get
{ {
return _remoteSyncClient; return _remotePartyService;
} }
} }
@ -58,7 +54,7 @@ namespace Aurora.Models.Media
public override async Task Load() public override async Task Load()
{ {
this.DataStream = new MemoryStream(); this.DataStream = new MemoryStream();
using (var call = _remotePlaybackClient.GetSongStream(new SongRequest() { Id = this.Id })) using (var call = _remotePartyService.StreamMedia(new StreamMediaRequest { Name = this.Id }))
{ {
try try
{ {

View File

@ -5,17 +5,17 @@ namespace Aurora.Proto.Party
/// <summary> /// <summary>
/// Partial PartyMember class with a constructor that generates a new id /// Partial PartyMember class with a constructor that generates a new id
/// </summary> /// </summary>
public partial class PartyMember public partial class Member
{ {
public PartyMember(string id) public Member(string id)
{ {
if (!string.IsNullOrWhiteSpace(id)) if (!string.IsNullOrWhiteSpace(id))
{ {
Id = id; Name = id;
} }
else else
{ {
Id = Guid.NewGuid().ToString(); Name = Guid.NewGuid().ToString();
} }
} }
} }

View File

@ -1,77 +0,0 @@
syntax = "proto3";
package Aurora.Proto.Events;
import "Proto/general.proto";
import "Proto/party.proto";
service RemoteEventService {
//Party Service
rpc GetEvents(EventsRequest) returns (stream BaseEvent) {};
rpc SubscribeToEvents(SubscribeRequest) returns(SubscriptionResponse);
rpc UnsubscribeFromEvents(UnsubscribeRequest) returns (SubscriptionResponse);
rpc UnsubscribeFromAll(UnsubscribeAllRequest) returns (SubscriptionResponse);
}
message EventsRequest {
string clientId = 1;
}
/* Subscription messages */
message SubscribeRequest {
repeated EventType eventTypes = 1;
string clientId = 2;
}
message UnsubscribeRequest {
repeated EventType eventTypes = 1;
string clientId = 2;
}
message UnsubscribeAllRequest {
string clientId = 1;
}
message SubscriptionResponse {
bool successful = 1;
}
/* Event Types */
enum EventType {
PartyMemberJoined = 0;
PartyMemberLeft = 1;
MediaPlaying = 2;
MediaStopped = 3;
}
message BaseEvent {
EventType eventType = 1;
string clientKey = 2;
oneof derivedEvent {
PartyMemberJoinedEvent partyMemberJoinedEvent = 3;
PartyMemberLeftEvent partyMemberLeftEvent = 4;
NewMediaPlayingEvent newMediaPlayingEvent = 5;
MediaPausedEvent mediaPausedEvent = 6;
MediaResumedEvent mediaResumedEvent = 7;
}
}
message NewMediaPlayingEvent {
Aurora.Proto.Party.RemoteMediaData media = 1;
}
message MediaResumedEvent {
Aurora.Proto.General.Empty empty = 1;
}
message MediaPausedEvent {
Aurora.Proto.General.Empty empty = 1;
}
message PartyMemberJoinedEvent {
Aurora.Proto.Party.PartyMember member = 1;
}
message PartyMemberLeftEvent {
Aurora.Proto.Party.PartyMember member = 1;
}

View File

@ -3,55 +3,287 @@ syntax = "proto3";
package Aurora.Proto.Party; package Aurora.Proto.Party;
import "Proto/general.proto"; import "Proto/general.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/field_mask.proto";
//Party
//Members
//EventSubscriptions
//Events
//Media
service RemotePartyService { service RemotePartyService {
//Party Service //**************
rpc JoinParty(JoinPartyRequest) returns (JoinPartyResponse); //Party Resource
rpc LeaveParty(LeavePartyRequest) returns (LeavePartyResponse); //**************
rpc GetPartyMembers(Aurora.Proto.General.Empty) returns (MembersResponse); //Get Party
rpc GetQueue(Aurora.Proto.General.Empty) returns (QueueResponse); rpc GetParty(Aurora.Proto.General.Empty) returns (Party);
//***************
//Member Resource
//***************
//List
rpc ListMembers(ListMembersRequest) returns (ListMembersResponse);
//Get
rpc GetMember(GetMemberRequest) returns (Member);
//Update
rpc UpdateMember(UpdateMemberRequest) returns (Member);
//Create
rpc CreateMember(CreateMemberRequest) returns (Member);
//Delete
rpc DeleteMember(DeleteMemberRequest) returns (Aurora.Proto.General.Empty) {};
//**************
//Media Resource
//**************
//List
rpc ListMedia(ListMediaRequest) returns (ListMediaResponse);
//Get
rpc GetMedia(GetMediaRequest) returns (Media);
//Create
rpc CreateMedia(CreateMediaRequest) returns (Media);
//Delete
rpc DeleteMedia(DeleteMediaRequest) returns (Aurora.Proto.General.Empty) {};
//CUSTOM: Stream
rpc StreamMedia(StreamMediaRequest) returns (stream Aurora.Proto.General.Chunk) {};
//CUSTOM: Sync
rpc SyncMedia(SyncMediaRequest) returns (stream Sync) {};
//***************************
//EventSubscriptions Resource
//***************************
//List
rpc ListEventSubscriptions(ListEventSubscriptionsRequest) returns (ListEventSubscriptionsResponse);
//Create
rpc CreateEventSubscription(CreateEventSubscriptionRequest) returns (EventSubscription);
//Delete
rpc DeleteEventSubscription(DeleteEventSubscriptionRequest) returns (Aurora.Proto.General.Empty);
//CUSTOM: Create EventSubscription List
rpc CreateEventSubscriptionList(CreateEventSubscriptionListRequest) returns (CreateEventSubscriptionListResponse);
//CUSTOM: Delete all
rpc DeleteAllEventSubscriptions(DeleteAllEventSubscriptionsRequest) returns (Aurora.Proto.General.Empty);
//*****
//Event
//*****
//Get
rpc GetEvents(GetEventsRequest) returns (stream BaseEvent) {};
} }
message JoinPartyRequest { message Party {
string userName = 2; //The resource name of the party
string name = 1;
string displayName = 2;
string description = 3;
string hostIp = 4;
Member hostMember = 5;
google.protobuf.Timestamp createdOn = 6;
} }
message JoinPartyResponse { enum PartyJoinedStatusEnum {
PartyJoinedStatusEnum status = 1; InParty = 0;
string clientId = 2; NotInParty = 1;
}
message LeavePartyRequest {
string clientId = 1;
} }
message LeavePartyResponse { message LeavePartyResponse {
PartyJoinedStatusEnum status = 1; PartyJoinedStatusEnum status = 1;
} }
message PartyMember { message Member {
string userName = 1; //Resource name of the party member to be returned (Added by server)
string id = 2; string name = 1;
string userName = 2;
//Added by server
string ipAddress = 3; string ipAddress = 3;
int32 port = 4;
} //Added by server
message MembersResponse { google.protobuf.Timestamp addedOn = 4;
repeated PartyMember members = 1;
} }
enum PartyJoinedStatusEnum { message ListMembersRequest {
Connected = 0; //Resource name of the parent of the members collection to be returned (The party)
Disconnected = 1; string parent = 1;
int32 pageSize = 2;
string pageToken = 3;
} }
message QueueResponse{ message ListMembersResponse {
repeated RemoteMediaData mediaList = 1; repeated Member members = 1;
string nextPageToken = 2;
}
message GetMemberRequest {
//Resource name of the member to be returned
string name = 1;
} }
message RemoteMediaData { message CreateMemberRequest {
string id = 1; //Resource name of the parent collection of the member to be created (The party)
string parent = 1;
Member member = 2;
}
message UpdateMemberRequest {
Member member = 1;
google.protobuf.FieldMask updateMask = 2;
}
message DeleteMemberRequest {
//Resource name of the member to be deleted
string name = 1;
}
message Media {
//Resource name of the remote media object
string name = 1;
string title = 2; string title = 2;
string artist = 3; string artist = 3;
string album = 4; string album = 4;
string duration = 5; string duration = 5;
} }
message ListMediaRequest {
//Resource name of the parent of the media collection to be listed (The party)
string parent = 1;
int32 pageSize = 2;
string pageToken = 3;
}
message ListMediaResponse {
repeated Media media = 1;
string nextPageToken = 3;
}
message GetMediaRequest {
//Resource name of the media requested
string name = 1;
}
message CreateMediaRequest {
//Resource name of the parent collection of the member to be created (The party)
string parent = 1;
Media media = 2;
}
message DeleteMediaRequest {
//Resource name of the member to be deleted
string name = 1;
}
message StreamMediaRequest {
//Resource name of the media requested
string name = 1;
}
message SyncMediaRequest {
//Resource name of the media to sync with
string name = 1;
}
message Sync {
int64 serverTimeTicks = 1;
float trackPosition= 2;
}
/* Event Types */
enum EventType {
MemberCreated = 0;
MemberDeleted = 1;
MediaPlaying = 2;
MediaStopped = 3;
}
message BaseEvent {
//Resource name of the event ?
string name = 1;
EventType eventType = 2;
string clientKey = 3;
oneof derivedEvent {
MemberCreatedEvent memberCreatedEvent = 4;
MemberDeletedEvent memberDeletedEvent = 5;
NewMediaPlayingEvent newMediaPlayingEvent = 6;
MediaPausedEvent mediaPausedEvent = 7;
MediaResumedEvent mediaResumedEvent = 8;
}
}
message NewMediaPlayingEvent {
Media media = 1;
}
message MediaResumedEvent {
Aurora.Proto.General.Empty empty = 1;
}
message MediaPausedEvent {
Aurora.Proto.General.Empty empty = 1;
}
message MemberCreatedEvent {
Member member = 1;
}
message MemberDeletedEvent {
string memberName = 1;
}
message EventSubscription {
EventType type = 2;
}
message ListEventSubscriptionsRequest {
//Resource name of parent to the subscription list (The member)
string parent = 1;
int32 pageSize = 2;
string pageToken = 3;
}
message ListEventSubscriptionsResponse {
repeated EventSubscription subscriptions = 1;
}
message CreateEventSubscriptionRequest {
//Resource name of the parent to the subscription list (The member)
string parent = 1;
EventSubscription eventSubscription = 2;
}
message DeleteEventSubscriptionRequest {
//Resource name of the subscription to delete
string parent = 1;
EventType type = 2;
}
message CreateEventSubscriptionListRequest {
//Resource name of the parent to the subscription list (The member)
string parent = 1;
repeated EventSubscription eventSubscriptions = 2;
}
message CreateEventSubscriptionListResponse {
repeated EventSubscription eventSubscriptions = 1;
}
message DeleteAllEventSubscriptionsRequest {
//Resource name of the parent to the subscription list (the member)
string parent = 1;
}
message GetEventsRequest {
//Resource name of the parent to the event stream (the member)
string parent = 1;
}

View File

@ -1,276 +0,0 @@
syntax = "proto3";
package Aurora.Proto.PartyV2;
import "Proto/general.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/field_mask.proto";
//Party
//Members
//EventSubscriptions
//Events
//Media
service RemotePartyService {
//**************
//Party Resource
//**************
//Get Party
rpc GetParty(Aurora.Proto.General.Empty) returns (Party);
//***************
//Member Resource
//***************
//List
rpc ListMembers(ListMembersRequest) returns (ListMembersResponse);
//Get
rpc GetMember(GetMemberRequest) returns (Member);
//Update
rpc UpdateMember(UpdateMemberRequest) returns (Member);
//Create
rpc CreateMember(CreateMemberRequest) returns (Member);
//Delete
rpc DeleteMember(DeleteMemberRequest) returns (Aurora.Proto.General.Empty) {};
//**************
//Media Resource
//**************
//List
rpc ListMedia(ListMediaRequest) returns (ListMediaResponse);
//Get
rpc GetMedia(GetMediaRequest) returns (Media);
//Create
rpc CreateMedia(CreateMediaRequest) returns (Media);
//Delete
rpc DeleteMedia(DeleteMediaRequest) returns (Aurora.Proto.General.Empty) {};
//CUSTOM: Stream
rpc StreamMedia(StreamMediaRequest) returns (stream Aurora.Proto.General.Chunk) {};
//CUSTOM: Sync
rpc SyncMedia(SyncMediaRequest) returns (stream Sync) {};
//***************************
//EventSubscriptions Resource
//***************************
//List
rpc ListEventSubscriptions(ListEventSubscriptionsRequest) returns (ListEventSubscriptionsResponse);
//Create
rpc CreateEventSubscription(CreateEventSubscriptionRequest) returns (EventSubscription);
//Delete
rpc DeleteEventSubscription(DeleteEventSubscriptionRequest) returns (Aurora.Proto.General.Empty);
//CUSTOM: Delete all
rpc DeleteAllEventSubscriptions(DeleteAllEventSubscriptionsRequest) returns (Aurora.Proto.General.Empty);
//*****
//Event
//*****
//Get
rpc GetEvents(GetEventsRequest) returns (stream BaseEvent) {};
}
message Party {
//The resource name of the party
string name = 1;
string displayName = 2;
string description = 3;
string hostIp = 4;
Member hostMember = 5;
google.protobuf.Timestamp createdOn = 6;
}
enum PartyJoinedStatusEnum {
InParty = 0;
NotInParty = 1;
}
message LeavePartyResponse {
PartyJoinedStatusEnum status = 1;
}
message Member {
//Resource name of the party member to be returned (Added by server)
string name = 1;
string userName = 2;
//Added by server
string ipAddress = 3;
//Added by server
google.protobuf.Timestamp addedOn = 4;
}
message ListMembersRequest {
//Resource name of the parent of the members collection to be returned (The party)
string parent = 1;
int32 pageSize = 2;
string pageToken = 3;
}
message ListMembersResponse {
repeated Member members = 1;
string nextPageToken = 2;
}
message GetMemberRequest {
//Resource name of the member to be returned
string name = 1;
}
message CreateMemberRequest {
//Resource name of the parent collection of the member to be created (The party)
string parent = 1;
Member member = 2;
}
message UpdateMemberRequest {
Member member = 1;
google.protobuf.FieldMask updateMask = 2;
}
message DeleteMemberRequest {
//Resource name of the member to be deleted
string name = 1;
}
message Media {
//Resource name of the remote media object
string name = 1;
string title = 2;
string artist = 3;
string album = 4;
string duration = 5;
}
message ListMediaRequest {
//Resource name of the parent of the media collection to be listed (The party)
string parent = 1;
int32 pageSize = 2;
string pageToken = 3;
}
message ListMediaResponse {
repeated Media media = 1;
string nextPageToken = 3;
}
message GetMediaRequest {
//Resource name of the media requested
string name = 1;
}
message CreateMediaRequest {
//Resource name of the parent collection of the member to be created (The party)
string parent = 1;
Media media = 2;
}
message DeleteMediaRequest {
//Resource name of the member to be deleted
string name = 1;
}
message StreamMediaRequest {
//Resource name of the media requested
string name = 1;
}
message SyncMediaRequest {
//Resource name of the media to sync with
string name = 1;
}
message Sync {
int64 serverTimeTicks = 1;
float trackPosition= 2;
}
/* Event Types */
enum EventType {
MemberCreated = 0;
MemberDeleted = 1;
MediaPlaying = 2;
MediaStopped = 3;
}
message BaseEvent {
//Resource name of the event ?
string name = 1;
EventType eventType = 2;
string clientKey = 3;
oneof derivedEvent {
MemberCreatedEvent memberCreatedEvent = 4;
MemberDeletedEvent memberDeletedEvent = 5;
NewMediaPlayingEvent newMediaPlayingEvent = 6;
MediaPausedEvent mediaPausedEvent = 7;
MediaResumedEvent mediaResumedEvent = 8;
}
}
message NewMediaPlayingEvent {
Media media = 1;
}
message MediaResumedEvent {
Aurora.Proto.General.Empty empty = 1;
}
message MediaPausedEvent {
Aurora.Proto.General.Empty empty = 1;
}
message MemberCreatedEvent {
Member member = 1;
}
message MemberDeletedEvent {
string memberName = 1;
}
message EventSubscription {
EventType type = 2;
}
message ListEventSubscriptionsRequest {
//Resource name of parent to the subscription list (The member)
string parent = 1;
int32 pageSize = 2;
string pageToken = 3;
}
message ListEventSubscriptionsResponse {
repeated EventSubscription subscriptions = 1;
}
message CreateEventSubscriptionRequest {
//Resource name of the parent to the subscription list (The member)
string parent = 1;
EventSubscription eventSubscription = 2;
}
message DeleteEventSubscriptionRequest {
//Resource name of the subscription to delete
string parent = 1;
EventType type = 2;
}
message DeleteAllEventSubscriptionsRequest {
//Resource name of the parent to the subscription list (the member)
string parent = 1;
}
message GetEventsRequest {
//Resource name of the parent to the event stream (the member)
string parent = 1;
}

View File

@ -1,13 +0,0 @@
syntax = "proto3";
package Aurora.Proto.Playback;
import "Proto/general.proto";
service RemotePlaybackService {
rpc GetSongStream(SongRequest) returns (stream Aurora.Proto.General.Chunk) {};
}
message SongRequest {
string id = 1;
}

View File

@ -1,15 +0,0 @@
syntax = "proto3";
package Aurora.Proto.Sync;
import "Proto/general.proto";
import "google/protobuf/timestamp.proto";
service RemoteSyncService {
rpc GetMediaSync(Aurora.Proto.General.Empty) returns (stream Sync) {};
}
message Sync {
int64 serverTimeTicks = 1;
float trackPosition= 2;
}

View File

@ -1,97 +0,0 @@
using System;
using System.Threading.Tasks;
using System.Threading;
using System.Collections.Generic;
using Aurora.Services;
using Aurora.Utils;
using System.Linq;
using Aurora.Services.EventManager;
using Aurora.Proto.Events;
namespace Aurora.RemoteImpl
{
public class RemoteEventServiceImpl : RemoteEventService.RemoteEventServiceBase
{
public RemoteEventServiceImpl()
{
}
/// <summary>
/// RPC for getting event stream for a particular client.
/// </summary>
/// <param name="request">Empty</param>
/// <param name="responseStream">The response stream</param>
/// <param name="context">gRPC client context</param>
/// <returns></returns>
public override Task GetEvents(EventsRequest request,
Grpc.Core.IServerStreamWriter<BaseEvent> responseStream,
Grpc.Core.ServerCallContext context)
{
string peerId = Misc.Combine(new string[] { context.Peer, request.ClientId });
Console.WriteLine(string.Format("SERVER - Events request received from peer: {0}", peerId));
AutoResetEvent are = new AutoResetEvent(false);
Action<BaseEvent> callback = (BaseEvent bEvent) =>
{
Console.WriteLine(string.Format("SERVER - Event fired for peer: {0}", peerId));
//TODO need to remove callback if stream no longer exists IE. Client crashed or stopped
responseStream.WriteAsync(bEvent);
};
Action cancelled = () =>
{
are.Set();
};
EventManager.Instance.AddEventHandler(callback, cancelled, Misc.Combine(new string[] { context.Peer, request.ClientId }));
are.WaitOne();
return Task.FromResult<object>(null);
}
/// <summary>
/// RPC for subscribing to remote events
/// </summary>
/// <param name="request">SubscribeRequest</param>
/// <param name="context">gRPC client context</param>
/// <returns></returns>
public override Task<SubscriptionResponse> SubscribeToEvents(SubscribeRequest request, Grpc.Core.ServerCallContext context)
{
Console.WriteLine(string.Format("SERVER - Subscription from client with id: {0}", request.ClientId));
EventManager.Instance.AddSubscriptionList(Misc.Combine(new string[] { context.Peer, request.ClientId }), request.EventTypes.ToList());
return Task.FromResult(new SubscriptionResponse { Successful = true });
}
/// <summary>
/// RPC for unsubscibing from events
/// </summary>
/// <param name="request">UnsubscribeRequest</param>
/// <param name="context">gRPC client context</param>
/// <returns></returns>
public override Task<SubscriptionResponse> UnsubscribeFromEvents(UnsubscribeRequest request, Grpc.Core.ServerCallContext context)
{
EventType[] eventTypes = null;
request.EventTypes.CopyTo(eventTypes, 0);
EventManager.Instance.RemoveSubscriptionList(Misc.Combine(new string[] { context.Peer, request.ClientId }), eventTypes.ToList());
return Task.FromResult(new SubscriptionResponse { Successful = true });
}
/// <summary>
/// RPC for unsubscribing from all events
/// </summary>
/// <param name="request">UnsubscribeAllRequest</param>
/// <param name="context">gRPC client context</param>
/// <returns></returns>
public override Task<SubscriptionResponse> UnsubscribeFromAll(UnsubscribeAllRequest request, Grpc.Core.ServerCallContext context)
{
EventManager.Instance.RemoveAllSubscriptions(Misc.Combine(new string[] { context.Peer, request.ClientId }));
return Task.FromResult(new SubscriptionResponse { Successful = true });
}
}
}

View File

@ -1,148 +0,0 @@
using System;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using System.Linq;
using Aurora.Utils;
using Aurora.Proto.Party;
using Aurora.Proto.Events;
using Aurora.Services.EventManager;
using Aurora.Models.Media;
using Aurora.Services.Library;
using Autofac;
namespace Aurora.RemoteImpl
{
public class RemotePartyServiceImpl : RemotePartyService.RemotePartyServiceBase
{
/// <summary>
/// Dictionary of party members. Key -> ClientId
/// </summary>
private ObservableCollection<PartyMember> _partyMembers;
public RemotePartyServiceImpl()
{
_partyMembers = new ObservableCollection<PartyMember>();
}
public ObservableCollection<PartyMember> PartyMembers
{
get
{
return _partyMembers;
}
}
public override Task<JoinPartyResponse> JoinParty(JoinPartyRequest request, Grpc.Core.ServerCallContext context)
{
PartyMember partyMember = new PartyMember("")
{
UserName = request.UserName,
IpAddress = context.Host,
};
Console.WriteLine("SERVER - Client joined party: " + partyMember.Id);
_partyMembers.Add(partyMember);
BaseEvent e = new BaseEvent
{
EventType = EventType.PartyMemberJoined,
PartyMemberJoinedEvent = new PartyMemberJoinedEvent
{
Member = partyMember,
}
};
EventManager.Instance.FireEvent(e);
JoinPartyResponse response = new JoinPartyResponse() { Status = PartyJoinedStatusEnum.Connected, ClientId = partyMember.Id };
return Task.FromResult(response);
}
public override Task<LeavePartyResponse> LeaveParty(LeavePartyRequest request, Grpc.Core.ServerCallContext context)
{
PartyMember partyMember = _partyMembers.Where(e => e.Id == request.ClientId).Single();
_partyMembers.Remove(partyMember);
BaseEvent bv = new BaseEvent
{
EventType = EventType.PartyMemberJoined,
PartyMemberLeftEvent = new PartyMemberLeftEvent
{
Member = partyMember,
}
};
EventManager.Instance.FireEvent(bv);
EventManager.Instance.RemoveAllSubscriptions(Misc.Combine(new string[] { context.Peer, request.ClientId }));
EventManager.Instance.CancelEventStream(Misc.Combine(new string[] { context.Peer, request.ClientId }));
LeavePartyResponse response = new LeavePartyResponse() { Status = PartyJoinedStatusEnum.Disconnected };
return Task.FromResult(response);
}
public override Task<MembersResponse> GetPartyMembers(Proto.General.Empty empty, Grpc.Core.ServerCallContext context)
{
MembersResponse response = new MembersResponse();
response.Members.AddRange(_partyMembers);
return Task.FromResult(response);
}
public override Task<QueueResponse> GetQueue(Proto.General.Empty empty, Grpc.Core.ServerCallContext context)
{
QueueResponse mediaList = new QueueResponse();
//This will change as queuing operation gets solidified
//Simply return the hosts library
using (var scope = App.Container.BeginLifetimeScope())
{
ILibraryService library = scope.Resolve<ILibraryService>();
ObservableCollection<BaseMedia> queue = library.GetLibrary();
foreach (BaseMedia media in queue)
{
AudioMetadata metadata = new AudioMetadata();
try
{
if (media.Metadata is AudioMetadata)
{
metadata = media.Metadata as AudioMetadata;
RemoteMediaData data = new RemoteMediaData();
data.Id = media.Id;
if (metadata.Title != null)
{
data.Title = metadata.Title;
}
if (metadata.Artist != null)
{
data.Artist = metadata.Artist;
}
if (metadata.Album != null)
{
data.Album = metadata.Album;
}
if (metadata.Duration != null)
{
data.Duration = metadata.Duration;
}
mediaList.MediaList.Add(data);
}
}
catch (Exception ex)
{
Console.WriteLine(string.Format("Error preparing queue: {0}", ex.Message));
}
}
}
return Task.FromResult(mediaList);
}
}
}

View File

@ -1,57 +0,0 @@
using System;
using System.Threading.Tasks;
using Aurora.Proto.Playback;
using Aurora.Proto.General;
using Aurora.Models.Media;
using Aurora.Services.Library;
using Autofac;
namespace Aurora.RemoteImpl
{
public class RemotePlaybackServiceImpl : RemotePlaybackService.RemotePlaybackServiceBase
{
public override async Task GetSongStream(SongRequest request,
Grpc.Core.IServerStreamWriter<Chunk> responseStream,
Grpc.Core.ServerCallContext context)
{
using (var scope = App.Container.BeginLifetimeScope())
{
ILibraryService library = scope.Resolve<ILibraryService>();
BaseMedia originalSong = library.GetSong(request.Id);
if (!(originalSong is LocalAudio))
{
return;
}
//Copy media object to not interfere with other threads
LocalAudio songCopy = new LocalAudio((LocalAudio)originalSong);
try
{
//Load only if not already loaded. (Multiple clients may be requesting media)
if (!songCopy.IsLoaded)
{
await songCopy.Load();
}
//Send stream
Console.WriteLine("Begin sending file");
byte[] buffer = new byte[2048]; // read in chunks of 2KB
int bytesRead;
while ((bytesRead = songCopy.DataStream.Read(buffer, 0, buffer.Length)) > 0)
{
Google.Protobuf.ByteString bufferByteString = Google.Protobuf.ByteString.CopyFrom(buffer);
await responseStream.WriteAsync(new Chunk { Content = bufferByteString });
}
Console.WriteLine("Done sending file");
}
catch (Exception ex)
{
Console.WriteLine("Exception caught while sending audio file: " + ex.Message);
}
}
}
}
}

View File

@ -1,56 +0,0 @@
using System;
using System.Threading.Tasks;
using Aurora.Proto.Sync;
using Aurora.Proto.General;
using Aurora.Services.Player;
using Aurora;
using Autofac;
namespace Aurora.RemoteImpl
{
public class RemoteSyncServiceImpl : RemoteSyncService.RemoteSyncServiceBase
{
/// <summary>
/// RPC for getting a stream of media syncs
/// </summary>
/// <param name="request"></param>
/// <param name="responseStream"></param>
/// <param name="context"></param>
/// <returns></returns>
public override async Task GetMediaSync(Empty request,
Grpc.Core.IServerStreamWriter<Sync> responseStream,
Grpc.Core.ServerCallContext context)
{
using (var scope = App.Container.BeginLifetimeScope())
{
IPlayer player = scope.Resolve<IPlayer>();
bool continueSync = true;
string currentId = player.CurrentMedia.Id;
MediaChangedEventHandler mediaChanged = (sender, e) =>
{
if (e.NewId != currentId)
{
continueSync = false;
}
};
player.MediaChanged += mediaChanged;
while (continueSync)
{
float length = player.CurrentMediaLength;
Sync sync = new Sync()
{
TrackPosition = player.CurrentMediaPosition,
ServerTimeTicks = Utils.TimeUtils.GetNetworkTime().DateTime.Ticks
};
await responseStream.WriteAsync(sync);
Console.WriteLine("Sent Sync");
await Task.Delay(5000);
}
}
}
}
}

View File

@ -1,22 +0,0 @@
using System;
namespace Aurora.Services
{
public abstract class BaseService<T> where T : class
{
private static volatile Lazy<T> _instance = new Lazy<T>(() => CreateInstanceOfT());
public static T Instance
{
get { return _instance.Value; }
}
private static T CreateInstanceOfT()
{
return Activator.CreateInstance(typeof(T), true) as T;
}
}
}

View File

@ -0,0 +1,46 @@
using Grpc.Core;
using Aurora.Proto.Party;
using Aurora.Services.Settings;
namespace Aurora.Services.Client
{
public class ClientService : IClientService
{
private RemotePartyService.RemotePartyServiceClient _remotePartyClient;
private Channel _channel;
private ISettingsService _settingsService;
public ClientService(ISettingsService settingsService)
{
this._settingsService = settingsService;
}
public bool IsStarted
{
get
{
return _remotePartyClient != null;
}
}
public RemotePartyService.RemotePartyServiceClient RemotePartyServiceClient
{
get { return this._remotePartyClient; }
}
public void Start(string hostname, string port)
{
_channel = new Channel(string.Format("{0}:{1}", hostname, port), ChannelCredentials.Insecure);
_remotePartyClient = new RemotePartyService.RemotePartyServiceClient(_channel);
}
public async void Close()
{
await _channel.ShutdownAsync();
_remotePartyClient = null;
}
}
}

View File

@ -0,0 +1,15 @@
using Aurora.Proto.Party;
namespace Aurora.Services.Client
{
public interface IClientService
{
bool IsStarted { get; }
RemotePartyService.RemotePartyServiceClient RemotePartyServiceClient { get; }
void Start(string hostname, string port);
void Close();
}
}

View File

@ -1,152 +0,0 @@
using System;
using System.Threading.Tasks;
using System.Threading;
using Grpc.Core;
using Aurora.Proto.Events;
using Aurora.Proto.Party;
using Aurora.Proto.Playback;
using Aurora.Proto.Sync;
using Aurora.Services.ClientService.Events;
using System.Collections.Generic;
using Aurora.Services.Settings;
namespace Aurora.Services.ClientService
{
public class ClientService : IClientService
{
private RemotePartyService.RemotePartyServiceClient _remotePartyClient;
private RemoteEventService.RemoteEventServiceClient _remoteEventsClient;
private RemotePlaybackService.RemotePlaybackServiceClient _remotePlaybackClient;
private RemoteSyncService.RemoteSyncServiceClient _remoteSyncClient;
private Channel _channel;
private CancellationTokenSource _eventCancellationTokenSource;
private ISettingsService _settingsService;
public ClientService(ISettingsService settingsService)
{
this._settingsService = settingsService;
}
public MediaPausedEventHandler OnMediaPaused { get; set; }
public NewMediaPlayingEventHandler OnNewMediaPlaying { get; set; }
public PartyMemberJoinedEventHandler OnPartyMemberJoined { get; set; }
public PartyMemberLeftEventHandler OnPartyMemberLeft { get; set; }
public MediaResumedEventHandler OnMediaResumed { get; set; }
public RemotePartyService.RemotePartyServiceClient RemotePartyClient
{
get
{
return _remotePartyClient;
}
}
public RemoteEventService.RemoteEventServiceClient RemoteEventClient
{
get { return _remoteEventsClient; }
}
public RemotePlaybackService.RemotePlaybackServiceClient RemotePlaybackClient
{
get { return _remotePlaybackClient; }
}
public RemoteSyncService.RemoteSyncServiceClient RemoteSyncClient
{
get { return _remoteSyncClient; }
}
public bool IsStarted
{
get
{
return _remoteEventsClient != null &&
_remotePartyClient != null;
}
}
public bool IsHost { get; set; }
public void Start(string hostname, string port)
{
_channel = new Channel(string.Format("{0}:{1}", hostname, port), ChannelCredentials.Insecure);
_remotePartyClient = new RemotePartyService.RemotePartyServiceClient(_channel);
_remoteEventsClient = new RemoteEventService.RemoteEventServiceClient(_channel);
_remotePlaybackClient = new RemotePlaybackService.RemotePlaybackServiceClient(_channel);
_remoteSyncClient = new RemoteSyncService.RemoteSyncServiceClient(_channel);
}
public async void Close()
{
_eventCancellationTokenSource.Cancel();
await _channel.ShutdownAsync();
_remotePartyClient = null;
_remoteEventsClient = null;
_remotePlaybackClient = null;
_remoteSyncClient = null;
}
/// <summary>
/// Asynchronous function for processing events off of the event stream.
/// </summary>
/// <returns></returns>
public async Task GetEvents()
{
_eventCancellationTokenSource = new CancellationTokenSource();
string clientId = this._settingsService.ClientId;
Console.WriteLine(string.Format("CLIENT {0} - GetEvents called from client with id", clientId));
using (AsyncServerStreamingCall<BaseEvent> eventStream = _remoteEventsClient
.GetEvents(new EventsRequest { ClientId = this._settingsService.ClientId }))
{
try
{
while (!_eventCancellationTokenSource.Token.IsCancellationRequested &&
await eventStream.ResponseStream.MoveNext(_eventCancellationTokenSource.Token))
{
try
{
BaseEvent e = new BaseEvent(eventStream.ResponseStream.Current);
Dictionary<BaseEvent.DerivedEventOneofCase, EventInfo> events = new Dictionary<BaseEvent.DerivedEventOneofCase, EventInfo>()
{
{BaseEvent.DerivedEventOneofCase.MediaPausedEvent, new EventInfo(this.OnMediaPaused, typeof(MediaPausedEventArgs))},
{BaseEvent.DerivedEventOneofCase.MediaResumedEvent, new EventInfo(this.OnMediaResumed, typeof(MediaResumedEventArgs))},
{BaseEvent.DerivedEventOneofCase.NewMediaPlayingEvent, new EventInfo(this.OnNewMediaPlaying, typeof(NewMediaPlayingEventArgs))},
{BaseEvent.DerivedEventOneofCase.PartyMemberJoinedEvent, new EventInfo(this.OnPartyMemberJoined, typeof(PartyMemberJoinedEventArgs))},
{BaseEvent.DerivedEventOneofCase.PartyMemberLeftEvent, new EventInfo(this.OnPartyMemberLeft, typeof(PartyMemberLeftEventArgs))}
};
events.TryGetValue(e.DerivedEventCase, out EventInfo eventInfo);
if (eventInfo != null && eventInfo.Handler != null)
{
eventInfo.Handler.DynamicInvoke(new object[] { this, Activator.CreateInstance(eventInfo.ArgsType, new object[] { e }) });
}
}
catch (Exception ex)
{
Console.WriteLine("Exception while parsing event ---" + ex.Message);
}
}
}
catch (Exception ex)
{
Console.WriteLine(string.Format("EXCEPTION while parsing events --- " + ex.Message));
}
}
}
public void StopEvents()
{
if (_eventCancellationTokenSource != null && !_eventCancellationTokenSource.IsCancellationRequested)
{
_eventCancellationTokenSource.Cancel();
}
}
}
}

View File

@ -1,25 +0,0 @@
using System;
using System.Threading.Tasks;
using System.Threading;
using Grpc.Core;
using Aurora.Proto.Events;
using Aurora.Proto.Party;
using Aurora.Proto.Playback;
using Aurora.Proto.Sync;
using Aurora.Services.ClientService.Events;
using System.Collections.Generic;
namespace Aurora.Services.ClientService
{
public class EventInfo
{
public EventInfo(Delegate handler, Type argsType)
{
this.Handler = handler;
ArgsType = argsType;
}
public Delegate Handler { get; private set; }
public Type ArgsType { get; private set; }
}
}

View File

@ -1,16 +0,0 @@
using System;
using Aurora.Proto.Events;
namespace Aurora.Services.ClientService.Events
{
public delegate void MediaPausedEventHandler(object sender, MediaPausedEventArgs e);
public class MediaPausedEventArgs
{
public MediaPausedEvent Event { get; private set; }
public MediaPausedEventArgs(BaseEvent e)
{
Event = e.MediaPausedEvent;
}
}
}

View File

@ -1,16 +0,0 @@
using System;
using Aurora.Proto.Events;
namespace Aurora.Services.ClientService
{
public delegate void MediaResumedEventHandler(object sender, MediaResumedEventArgs e);
public class MediaResumedEventArgs
{
public MediaResumedEvent Event { get; private set; }
public MediaResumedEventArgs(BaseEvent e)
{
Event = e.MediaResumedEvent;
}
}
}

View File

@ -1,16 +0,0 @@
using System;
using Aurora.Proto.Events;
namespace Aurora.Services.ClientService.Events
{
public delegate void NewMediaPlayingEventHandler(object sender, NewMediaPlayingEventArgs e);
public class NewMediaPlayingEventArgs
{
public NewMediaPlayingEvent Event { get; private set; }
public NewMediaPlayingEventArgs(BaseEvent e)
{
Event = e.NewMediaPlayingEvent;
}
}
}

View File

@ -1,16 +0,0 @@
using System;
using Aurora.Proto.Events;
namespace Aurora.Services.ClientService.Events
{
public delegate void PartyMemberJoinedEventHandler(object sender, PartyMemberJoinedEventArgs e);
public class PartyMemberJoinedEventArgs
{
public PartyMemberJoinedEvent Event { get; private set; }
public PartyMemberJoinedEventArgs(BaseEvent e)
{
Event = e.PartyMemberJoinedEvent;
}
}
}

View File

@ -1,16 +0,0 @@
using System;
using Aurora.Proto.Events;
namespace Aurora.Services.ClientService.Events
{
public delegate void PartyMemberLeftEventHandler(object sender, PartyMemberLeftEventArgs e);
public class PartyMemberLeftEventArgs
{
public PartyMemberLeftEvent Event { get; private set; }
public PartyMemberLeftEventArgs(BaseEvent e)
{
Event = e.PartyMemberLeftEvent;
}
}
}

View File

@ -1,42 +0,0 @@
using Aurora.Services.ClientService.Events;
using Aurora.Proto.Events;
using Aurora.Proto.Party;
using Aurora.Proto.Playback;
using Aurora.Proto.Sync;
using System.Threading.Tasks;
namespace Aurora.Services.ClientService
{
public interface IClientService
{
MediaPausedEventHandler OnMediaPaused { get; set; }
NewMediaPlayingEventHandler OnNewMediaPlaying { get; set; }
PartyMemberJoinedEventHandler OnPartyMemberJoined { get; set; }
PartyMemberLeftEventHandler OnPartyMemberLeft { get; set; }
MediaResumedEventHandler OnMediaResumed { get; set; }
RemotePartyService.RemotePartyServiceClient RemotePartyClient { get; }
RemoteEventService.RemoteEventServiceClient RemoteEventClient { get; }
RemotePlaybackService.RemotePlaybackServiceClient RemotePlaybackClient { get; }
RemoteSyncService.RemoteSyncServiceClient RemoteSyncClient { get; }
bool IsStarted { get; }
bool IsHost { get; set; }
void Start(string hostname, string port);
void Close();
/// <summary>
/// Asynchronous function for processing events off of the event stream.
/// </summary>
/// <returns></returns>
Task GetEvents();
void StopEvents();
}
}

View File

@ -2,9 +2,9 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Aurora.Proto.PartyV2; using Aurora.Proto.Party;
namespace Aurora.Services.Server.EventManager namespace Aurora.Services.EventManager
{ {
public class EventAction public class EventAction
{ {

View File

@ -1,23 +1,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Aurora.Proto.Events; using Aurora.Proto.Party;
namespace Aurora.Services.EventManager namespace Aurora.Services.EventManager
{ {
public class EventAction public class EventManager : IEventManager
{
public EventAction(Action<BaseEvent> callback, Action cancel)
{
Callback = callback;
Cancel = cancel;
}
public Action<BaseEvent> Callback { get; set; }
public Action Cancel { get; set; }
}
public class EventManager : BaseService<EventManager>
{ {
#region Fields #region Fields
private Dictionary<string, List<EventType>> _subscriptionList; private Dictionary<string, List<EventType>> _subscriptionList;
@ -38,32 +27,32 @@ namespace Aurora.Services.EventManager
#region Public Methods #region Public Methods
/// <summary> /// <summary>
/// Get the list of event type subscriptions for a given session id. /// Get the list of event type subscriptions for a given sessionIdentifier id.
/// </summary> /// </summary>
/// <param name="session">Session Id</param> /// <param name="sessionIdentifier">sessionIdentifier Id</param>
/// <returns></returns> /// <returns></returns>
public List<EventType> GetSubscriptionList(string session) public List<EventType> GetSubscriptionList(string sessionIdentifier)
{ {
List<EventType> eventList = new List<EventType>(); List<EventType> eventList = new List<EventType>();
if (_subscriptionList.ContainsKey(session)) if (_subscriptionList.ContainsKey(sessionIdentifier))
{ {
_subscriptionList.TryGetValue(session, out eventList); _subscriptionList.TryGetValue(sessionIdentifier, out eventList);
} }
return eventList; return eventList;
} }
/// <summary> /// <summary>
/// Get the number of event subscriptions for a given session /// Get the number of event subscriptions for a given sessionIdentifier
/// </summary> /// </summary>
/// <param name="session">Session Id</param> /// <param name="sessionIdentifier">sessionIdentifier Id</param>
/// <returns></returns> /// <returns></returns>
public int GetSubscriptionCount(string session) public int GetSubscriptionCount(string sessionIdentifier)
{ {
List<EventType> eventList = new List<EventType>(); List<EventType> eventList = new List<EventType>();
if (_subscriptionList.ContainsKey(session)) if (_subscriptionList.ContainsKey(sessionIdentifier))
{ {
_subscriptionList.TryGetValue(session, out eventList); _subscriptionList.TryGetValue(sessionIdentifier, out eventList);
} }
return eventList.Count(); return eventList.Count();
@ -72,24 +61,24 @@ namespace Aurora.Services.EventManager
/// <summary> /// <summary>
/// Add a new subscription /// Add a new subscription
/// </summary> /// </summary>
/// <param name="session"></param> /// <param name="sessionIdentifier"></param>
/// <param name="type"></param> /// <param name="type"></param>
public bool AddSubscription(string session, EventType type) public bool AddSubscription(string sessionIdentifier, EventType type)
{ {
bool success = false; bool success = false;
lock (_subscriptionList) lock (_subscriptionList)
{ {
if (!_subscriptionList.ContainsKey(session)) if (!_subscriptionList.ContainsKey(sessionIdentifier))
{ {
//Add session to subscription list //Add sessionIdentifier to subscription list
List<EventType> eventList = new List<EventType>(); List<EventType> eventList = new List<EventType>();
eventList.Add(type); eventList.Add(type);
_subscriptionList.Add(session, eventList); _subscriptionList.Add(sessionIdentifier, eventList);
success = true; success = true;
} }
else else
{ {
_subscriptionList.TryGetValue(session, out List<EventType> eventList); _subscriptionList.TryGetValue(sessionIdentifier, out List<EventType> eventList);
if (eventList != null) if (eventList != null)
{ {
eventList.Add(type); eventList.Add(type);
@ -104,79 +93,82 @@ namespace Aurora.Services.EventManager
/// <summary> /// <summary>
/// Add a list of subscriptions. This unsubscribes from unused events. /// Add a list of subscriptions. This unsubscribes from unused events.
/// </summary> /// </summary>
/// <param name="session">The browser session id.</param> /// <param name="sessionIdentifier">The browser sessionIdentifier id.</param>
/// <param name="types">The list of event types to subscribe to.</param> /// <param name="types">The list of event types to subscribe to.</param>
public void AddSubscriptionList(string session, List<EventType> types) public void AddSubscriptionList(string sessionIdentifier, List<EventType> types)
{ {
RemoveAllSubscriptions(session); RemoveAllSubscriptions(sessionIdentifier);
foreach (EventType e in types) foreach (EventType e in types)
{ {
AddSubscription(session, e); AddSubscription(sessionIdentifier, e);
} }
} }
/// <summary> /// <summary>
/// Unsubscribe from a given event type. /// Unsubscribe from a given event type.
/// </summary> /// </summary>
/// <param name="session">Session Id</param> /// <param name="sessionIdentifier">sessionIdentifier Id</param>
/// <param name="type">Event Type to be removed</param> /// <param name="type">Event Type to be removed</param>
public void RemoveSubscription(string session, EventType type) public void RemoveSubscription(string sessionIdentifier, EventType type)
{ {
lock (_subscriptionList) lock (_subscriptionList)
{ {
if (_subscriptionList.ContainsKey(session)) if (_subscriptionList.ContainsKey(sessionIdentifier))
{ {
List<EventType> eventTypeList; List<EventType> eventTypeList;
_subscriptionList.TryGetValue(session, out eventTypeList); _subscriptionList.TryGetValue(sessionIdentifier, out eventTypeList);
if (eventTypeList != null && eventTypeList.Contains(type)) if (eventTypeList != null && eventTypeList.Contains(type))
{ {
eventTypeList.Remove(type); eventTypeList.Remove(type);
//base.LogInformation(string.Format("Subscription removed for event type {0} subscription on session {1}", type.ToString(), session)); //base.LogInformation(string.Format("Subscription removed for event type {0} subscription on sessionIdentifier {1}", type.ToString(), sessionIdentifier));
} }
} }
} }
} }
public void RemoveSubscriptionList(string session, List<EventType> types) public void RemoveSubscriptionList(string sessionIdentifier, List<EventType> types)
{ {
foreach (EventType e in types) foreach (EventType e in types)
{ {
RemoveSubscription(session, e); RemoveSubscription(sessionIdentifier, e);
} }
} }
/// <summary> /// <summary>
/// Remove all subscriptons for a given session. /// Remove all subscriptons for a given sessionIdentifier.
/// </summary> /// </summary>
/// <param name="session">Session Id</param> /// <param name="sessionIdentifier">sessionIdentifier Id</param>
public void RemoveAllSubscriptions(string session) public void RemoveAllSubscriptions(string sessionIdentifier)
{ {
if (_subscriptionList.ContainsKey(session)) if (_subscriptionList.ContainsKey(sessionIdentifier))
{ {
_subscriptionList.Remove(session); _subscriptionList.Remove(sessionIdentifier);
} }
} }
public void AddEventHandler(Action<BaseEvent> action, Action cancel, string sessionId) public void AddEventHandler(Action<BaseEvent> action, Action cancel, string sessionIdentifierId)
{ {
lock (_actionList) lock (_actionList)
{ {
_actionList.Add(sessionId, new EventAction(action, cancel)); _actionList.Add(sessionIdentifierId, new EventAction(action, cancel));
} }
} }
public void RemoveEventHandler(string sessionId) public void RemoveEventHandler(string sessionIdentifierId)
{ {
_actionList.Remove(sessionId); _actionList.Remove(sessionIdentifierId);
} }
public void CancelEventStream(string sessionId) public void CancelEventStream(string sessionIdentifierId)
{ {
_actionList.TryGetValue(sessionId, out EventAction value); _actionList.TryGetValue(sessionIdentifierId, out EventAction value);
value.Cancel(); if (value != null)
{
value.Cancel();
}
RemoveEventHandler(sessionId); RemoveEventHandler(sessionIdentifierId);
} }
public void FireEvent(BaseEvent bEvent) public void FireEvent(BaseEvent bEvent)

View File

@ -1,8 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Aurora.Proto.PartyV2; using Aurora.Proto.Party;
namespace Aurora.Services.Server.EventManager namespace Aurora.Services.EventManager
{ {
public interface IEventManager public interface IEventManager
{ {

View File

@ -3,8 +3,6 @@ using System.Threading.Tasks;
using System.Threading; using System.Threading;
using Grpc.Core; using Grpc.Core;
using Aurora.Models.Media; using Aurora.Models.Media;
using Aurora.Proto.Sync;
using LibVLCSharp.Shared;
namespace Aurora.Services.Player namespace Aurora.Services.Player
{ {

View File

@ -3,7 +3,7 @@ using System.Threading.Tasks;
using System.Threading; using System.Threading;
using Grpc.Core; using Grpc.Core;
using Aurora.Models.Media; using Aurora.Models.Media;
using Aurora.Proto.Sync; using Aurora.Proto.Party;
using LibVLCSharp.Shared; using LibVLCSharp.Shared;
namespace Aurora.Services.Player namespace Aurora.Services.Player
@ -85,7 +85,7 @@ namespace Aurora.Services.Player
} }
_currentMedia = media; _currentMedia = media;
await _currentMedia.Load(); await _currentMedia.Load();
var md = new Media(_libvlc, _currentMedia.DataStream); var md = new LibVLCSharp.Shared.Media(_libvlc, _currentMedia.DataStream);
_mediaPlayer = new MediaPlayer(md); _mediaPlayer = new MediaPlayer(md);
_mediaPlayer.Stopped += OnStopped; _mediaPlayer.Stopped += OnStopped;
md.Dispose(); md.Dispose();
@ -112,15 +112,15 @@ namespace Aurora.Services.Player
RemoteAudio media = _currentMedia as RemoteAudio; RemoteAudio media = _currentMedia as RemoteAudio;
if (!media.FromHost) if (!media.FromHost)
{ {
RemoteSyncService.RemoteSyncServiceClient remoteSyncClient = media.RemoteSyncClient; RemotePartyService.RemotePartyServiceClient remotePartyServiceClient = media.RemotePartyServiceClient;
//Sync playback in a separate task //Sync playback in a separate task
//Task completes when host stops syncing (when a song is complete) //Task completes when host stops syncing (when a song is complete)
Task syncTask = new Task(async () => Task syncTask = new Task(async () =>
{ {
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
using (AsyncServerStreamingCall<Sync> syncStream = remoteSyncClient using (AsyncServerStreamingCall<Sync> syncStream = remotePartyServiceClient
.GetMediaSync(new Proto.General.Empty())) .SyncMedia(new SyncMediaRequest() { }))
{ {
try try
{ {

View File

@ -1,11 +1,11 @@
using System; using System;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Collections.Generic; using System.Collections.Generic;
using Aurora.Proto.PartyV2; using Aurora.Proto.Party;
using Aurora.Services.Library; using Aurora.Services.Library;
using Aurora.Services.Settings; using Aurora.Services.Settings;
using Aurora.Models.Media; using Aurora.Models.Media;
using Aurora.Services.Server.EventManager; using Aurora.Services.EventManager;
using Autofac; using Autofac;
namespace Aurora.Services.Server.Controllers namespace Aurora.Services.Server.Controllers

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Threading; using System.Threading;
using Aurora.Proto.PartyV2; using Aurora.Proto.Party;
using Aurora.Utils; using Aurora.Utils;
namespace Aurora.Services.Server.Controllers namespace Aurora.Services.Server.Controllers

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Aurora.Proto.PartyV2; using System.Collections.Generic;
using Aurora.Proto.Party;
using Aurora.Proto.General; using Aurora.Proto.General;
using Aurora.Utils; using Aurora.Utils;
@ -8,12 +9,16 @@ namespace Aurora.Services.Server.Controllers
{ {
public partial class RemotePartyController : RemotePartyService.RemotePartyServiceBase public partial class RemotePartyController : RemotePartyService.RemotePartyServiceBase
{ {
public override Task<ListEventSubscriptionsResponse> ListEventSubscriptions(ListEventSubscriptionsRequest request, Grpc.Core.ServerCallContext context) public override Task<ListEventSubscriptionsResponse> ListEventSubscriptions(
ListEventSubscriptionsRequest request,
Grpc.Core.ServerCallContext context)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public override Task<EventSubscription> CreateEventSubscription(CreateEventSubscriptionRequest request, Grpc.Core.ServerCallContext context) public override Task<EventSubscription> CreateEventSubscription(
CreateEventSubscriptionRequest request,
Grpc.Core.ServerCallContext context)
{ {
Console.WriteLine(string.Format("SERVER - Subscription from client with id: {0}", request.Parent)); Console.WriteLine(string.Format("SERVER - Subscription from client with id: {0}", request.Parent));
this._eventManager.AddSubscription(Misc.Combine(new string[] { context.Peer, request.Parent }), request.EventSubscription.Type); this._eventManager.AddSubscription(Misc.Combine(new string[] { context.Peer, request.Parent }), request.EventSubscription.Type);
@ -21,14 +26,37 @@ namespace Aurora.Services.Server.Controllers
return Task.FromResult(request.EventSubscription); return Task.FromResult(request.EventSubscription);
} }
public override Task<Empty> DeleteEventSubscription(DeleteEventSubscriptionRequest request, Grpc.Core.ServerCallContext context) public override Task<CreateEventSubscriptionListResponse> CreateEventSubscriptionList(
CreateEventSubscriptionListRequest request,
Grpc.Core.ServerCallContext context)
{
Console.WriteLine(string.Format("SERVER - Subscription from client with id: {0}", request.Parent));
List<EventType> eventTypes = new List<EventType>();
foreach (EventSubscription subscription in request.EventSubscriptions)
{
eventTypes.Add(subscription.Type);
}
this._eventManager.AddSubscriptionList(Misc.Combine(new string[] { context.Peer, request.Parent }), eventTypes);
CreateEventSubscriptionListResponse resp = new CreateEventSubscriptionListResponse();
resp.EventSubscriptions.AddRange(request.EventSubscriptions);
return Task.FromResult(resp);
}
public override Task<Empty> DeleteEventSubscription(
DeleteEventSubscriptionRequest request,
Grpc.Core.ServerCallContext context)
{ {
this._eventManager.RemoveSubscription(Misc.Combine(new string[] { context.Peer, request.Parent }), request.Type); this._eventManager.RemoveSubscription(Misc.Combine(new string[] { context.Peer, request.Parent }), request.Type);
return Task.FromResult(new Empty()); return Task.FromResult(new Empty());
} }
public override Task<Empty> DeleteAllEventSubscriptions(DeleteAllEventSubscriptionsRequest request, Grpc.Core.ServerCallContext context) public override Task<Empty> DeleteAllEventSubscriptions(
DeleteAllEventSubscriptionsRequest request,
Grpc.Core.ServerCallContext context)
{ {
this._eventManager.RemoveAllSubscriptions(Misc.Combine(new string[] { context.Peer, request.Parent })); this._eventManager.RemoveAllSubscriptions(Misc.Combine(new string[] { context.Peer, request.Parent }));

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Collections.Generic; using System.Collections.Generic;
using Aurora.Proto.PartyV2; using Aurora.Proto.Party;
using Aurora.Models.Media; using Aurora.Models.Media;
using Aurora.Proto.General; using Aurora.Proto.General;
using Aurora.Services.Library; using Aurora.Services.Library;

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Collections.Generic; using System.Collections.Generic;
using Aurora.Proto.PartyV2; using Aurora.Proto.Party;
using Aurora.Proto.General; using Aurora.Proto.General;
using Aurora.Utils; using Aurora.Utils;
using Grpc.Core; using Grpc.Core;

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Collections.Generic; using System.Collections.Generic;
using Aurora.Proto.PartyV2; using Aurora.Proto.Party;
using Google.Protobuf.WellKnownTypes; using Google.Protobuf.WellKnownTypes;

View File

@ -1,216 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Aurora.Proto.PartyV2;
namespace Aurora.Services.Server.EventManager
{
public class EventManager : IEventManager
{
#region Fields
private Dictionary<string, List<EventType>> _subscriptionList;
private Dictionary<string, EventAction> _actionList;
#endregion Fields
public EventManager()
{
_subscriptionList = new Dictionary<string, List<EventType>>();
_actionList = new Dictionary<string, EventAction>();
}
#region Private Methods
#endregion Private Methods
#region Public Methods
/// <summary>
/// Get the list of event type subscriptions for a given sessionIdentifier id.
/// </summary>
/// <param name="sessionIdentifier">sessionIdentifier Id</param>
/// <returns></returns>
public List<EventType> GetSubscriptionList(string sessionIdentifier)
{
List<EventType> eventList = new List<EventType>();
if (_subscriptionList.ContainsKey(sessionIdentifier))
{
_subscriptionList.TryGetValue(sessionIdentifier, out eventList);
}
return eventList;
}
/// <summary>
/// Get the number of event subscriptions for a given sessionIdentifier
/// </summary>
/// <param name="sessionIdentifier">sessionIdentifier Id</param>
/// <returns></returns>
public int GetSubscriptionCount(string sessionIdentifier)
{
List<EventType> eventList = new List<EventType>();
if (_subscriptionList.ContainsKey(sessionIdentifier))
{
_subscriptionList.TryGetValue(sessionIdentifier, out eventList);
}
return eventList.Count();
}
/// <summary>
/// Add a new subscription
/// </summary>
/// <param name="sessionIdentifier"></param>
/// <param name="type"></param>
public bool AddSubscription(string sessionIdentifier, EventType type)
{
bool success = false;
lock (_subscriptionList)
{
if (!_subscriptionList.ContainsKey(sessionIdentifier))
{
//Add sessionIdentifier to subscription list
List<EventType> eventList = new List<EventType>();
eventList.Add(type);
_subscriptionList.Add(sessionIdentifier, eventList);
success = true;
}
else
{
_subscriptionList.TryGetValue(sessionIdentifier, out List<EventType> eventList);
if (eventList != null)
{
eventList.Add(type);
success = true;
}
}
}
return success;
}
/// <summary>
/// Add a list of subscriptions. This unsubscribes from unused events.
/// </summary>
/// <param name="sessionIdentifier">The browser sessionIdentifier id.</param>
/// <param name="types">The list of event types to subscribe to.</param>
public void AddSubscriptionList(string sessionIdentifier, List<EventType> types)
{
RemoveAllSubscriptions(sessionIdentifier);
foreach (EventType e in types)
{
AddSubscription(sessionIdentifier, e);
}
}
/// <summary>
/// Unsubscribe from a given event type.
/// </summary>
/// <param name="sessionIdentifier">sessionIdentifier Id</param>
/// <param name="type">Event Type to be removed</param>
public void RemoveSubscription(string sessionIdentifier, EventType type)
{
lock (_subscriptionList)
{
if (_subscriptionList.ContainsKey(sessionIdentifier))
{
List<EventType> eventTypeList;
_subscriptionList.TryGetValue(sessionIdentifier, out eventTypeList);
if (eventTypeList != null && eventTypeList.Contains(type))
{
eventTypeList.Remove(type);
//base.LogInformation(string.Format("Subscription removed for event type {0} subscription on sessionIdentifier {1}", type.ToString(), sessionIdentifier));
}
}
}
}
public void RemoveSubscriptionList(string sessionIdentifier, List<EventType> types)
{
foreach (EventType e in types)
{
RemoveSubscription(sessionIdentifier, e);
}
}
/// <summary>
/// Remove all subscriptons for a given sessionIdentifier.
/// </summary>
/// <param name="sessionIdentifier">sessionIdentifier Id</param>
public void RemoveAllSubscriptions(string sessionIdentifier)
{
if (_subscriptionList.ContainsKey(sessionIdentifier))
{
_subscriptionList.Remove(sessionIdentifier);
}
}
public void AddEventHandler(Action<BaseEvent> action, Action cancel, string sessionIdentifierId)
{
lock (_actionList)
{
_actionList.Add(sessionIdentifierId, new EventAction(action, cancel));
}
}
public void RemoveEventHandler(string sessionIdentifierId)
{
_actionList.Remove(sessionIdentifierId);
}
public void CancelEventStream(string sessionIdentifierId)
{
_actionList.TryGetValue(sessionIdentifierId, out EventAction value);
if (value != null)
{
value.Cancel();
}
RemoveEventHandler(sessionIdentifierId);
}
public void FireEvent(BaseEvent bEvent)
{
Dictionary<string, EventAction> actionsCopy = new Dictionary<string, EventAction>();
//Copy actions list
lock (_actionList)
{
foreach (KeyValuePair<string, EventAction> pair in _actionList)
{
actionsCopy.Add(pair.Key, pair.Value);
}
}
lock (_subscriptionList)
{
foreach (KeyValuePair<string, List<EventType>> pair in _subscriptionList)
{
Task.Delay(1000);
//If action list contains an action for id, invoke
if (actionsCopy.ContainsKey(pair.Key))
{
actionsCopy.TryGetValue(pair.Key, out EventAction action);
Task executionTask = new Task(() => action.Callback(bEvent));
//Execute task with exception handler
executionTask.ContinueWith((Task task) =>
{
var exception = executionTask.Exception;
Console.WriteLine(string.Format("SERVER --- Exception occurred firing event"));
this._actionList.Remove(pair.Key);
},
TaskContinuationOptions.OnlyOnFaulted);
executionTask.Start();
}
}
}
}
#endregion Public Methods
}
}

View File

@ -6,8 +6,8 @@ using Grpc.Core;
using Aurora.Services.Server.Controllers; using Aurora.Services.Server.Controllers;
using Aurora.Services.Settings; using Aurora.Services.Settings;
using Aurora.Services.Library; using Aurora.Services.Library;
using Aurora.Services.Server.EventManager; using Aurora.Services.EventManager;
using Aurora.Proto.PartyV2; using Aurora.Proto.Party;
namespace Aurora.Services.Server namespace Aurora.Services.Server

View File

@ -1,143 +0,0 @@
using System;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using Grpc.Core;
using Aurora.RemoteImpl;
using Aurora.Proto.Events;
using Aurora.Proto.Party;
using Aurora.Proto.Playback;
using Aurora.Proto.Sync;
using Aurora.Services.Settings;
using Autofac;
namespace Aurora.Services
{
public class ServerService : BaseService<ServerService>
{
private int _port;
private string _hostname;
private Grpc.Core.Server _server;
//Implementation class declarations
private RemotePartyServiceImpl _remotePartyServiceImpl;
private RemoteEventServiceImpl _remoteEventImpl;
private RemotePlaybackServiceImpl _remotePlaybackImpl;
private RemoteSyncServiceImpl _remoteSyncImpl;
/// <summary>
/// Constructor. Registers GRPC service implementations.
/// </summary>
public ServerService()
{
string host = GetLocalIPAddress();
using (var scope = App.Container.BeginLifetimeScope())
{
var service = scope.Resolve<ISettingsService>();
this._port = service.DefaultPort;
}
if (string.IsNullOrWhiteSpace(host))
{
throw new Exception("This device must have a valid IP address");
}
_hostname = host;
_server = new Grpc.Core.Server
{
Ports = { new ServerPort(_hostname, _port, ServerCredentials.Insecure) }
};
}
public int Port
{
get { return _port; }
}
public string Hostname
{
get { return _hostname; }
}
public bool Initialized
{
get
{
return (_remoteEventImpl != null &&
_remotePartyServiceImpl != null &&
_server != null);
}
}
/// <summary>
/// Start Server
/// </summary>
public void Start()
{
try
{
Console.WriteLine(string.Format("Starting gRPC server at hostname: {0}, port: {1}", _hostname, _port));
if (!Initialized)
{
//Construct implementations
_remotePartyServiceImpl = new RemotePartyServiceImpl();
_remoteEventImpl = new RemoteEventServiceImpl();
_remotePlaybackImpl = new RemotePlaybackServiceImpl();
_remoteSyncImpl = new RemoteSyncServiceImpl();
// Register grpc RemoteService with singleton server service
RegisterService(RemotePartyService.BindService(_remotePartyServiceImpl));
RegisterService(RemoteEventService.BindService(_remoteEventImpl));
RegisterService(RemotePlaybackService.BindService(_remotePlaybackImpl));
RegisterService(RemoteSyncService.BindService(_remoteSyncImpl));
}
_server.Start();
}
catch (Exception ex)
{
Console.WriteLine(string.Format("Error starting gRPC server: {0}", ex.Message));
}
}
/// <summary>
/// Shutdown server async.
/// </summary>
/// <returns>Task</returns>
public async Task Stop()
{
await _server.ShutdownAsync();
}
public async Task Reset()
{
await Stop();
_server = new Grpc.Core.Server
{
Ports = { new ServerPort("localhost", _port, ServerCredentials.Insecure) }
};
}
private void RegisterService(ServerServiceDefinition definition)
{
_server.Services.Add(definition);
}
public static string GetLocalIPAddress()
{
string returnIp = "";
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
returnIp = ip.ToString();
}
}
return returnIp;
}
}
}

View File

@ -22,7 +22,7 @@ namespace Aurora.Services.Settings
/// The current sessions clientId. This is assigned by the server. This is not persisted. /// The current sessions clientId. This is assigned by the server. This is not persisted.
/// </summary> /// </summary>
/// <value></value> /// <value></value>
string ClientId { get; set; } string ClientName { get; set; }
string LibraryLocation { get; set; } string LibraryLocation { get; set; }
} }

View File

@ -67,7 +67,7 @@ namespace Aurora.Services.Settings
/// The current sessions clientId. This is assigned by the server. This is not persisted. /// The current sessions clientId. This is assigned by the server. This is not persisted.
/// </summary> /// </summary>
/// <value></value> /// <value></value>
public string ClientId public string ClientName
{ {
get; set; get; set;
} }