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 { #region Fields private Dictionary> _subscriptionList; private Dictionary _actionList; #endregion Fields public EventManager() { _subscriptionList = new Dictionary>(); _actionList = new Dictionary(); } #region Private Methods #endregion Private Methods #region Public Methods /// /// Get the list of event type subscriptions for a given sessionIdentifier id. /// /// sessionIdentifier Id /// public List GetSubscriptionList(string sessionIdentifier) { List eventList = new List(); if (_subscriptionList.ContainsKey(sessionIdentifier)) { _subscriptionList.TryGetValue(sessionIdentifier, out eventList); } return eventList; } /// /// Get the number of event subscriptions for a given sessionIdentifier /// /// sessionIdentifier Id /// public int GetSubscriptionCount(string sessionIdentifier) { List eventList = new List(); if (_subscriptionList.ContainsKey(sessionIdentifier)) { _subscriptionList.TryGetValue(sessionIdentifier, out eventList); } return eventList.Count(); } /// /// Add a new subscription /// /// /// public bool AddSubscription(string sessionIdentifier, EventType type) { bool success = false; lock (_subscriptionList) { if (!_subscriptionList.ContainsKey(sessionIdentifier)) { //Add sessionIdentifier to subscription list List eventList = new List(); eventList.Add(type); _subscriptionList.Add(sessionIdentifier, eventList); success = true; } else { _subscriptionList.TryGetValue(sessionIdentifier, out List eventList); if (eventList != null) { eventList.Add(type); success = true; } } } return success; } /// /// Add a list of subscriptions. This unsubscribes from unused events. /// /// The browser sessionIdentifier id. /// The list of event types to subscribe to. public void AddSubscriptionList(string sessionIdentifier, List types) { RemoveAllSubscriptions(sessionIdentifier); foreach (EventType e in types) { AddSubscription(sessionIdentifier, e); } } /// /// Unsubscribe from a given event type. /// /// sessionIdentifier Id /// Event Type to be removed public void RemoveSubscription(string sessionIdentifier, EventType type) { lock (_subscriptionList) { if (_subscriptionList.ContainsKey(sessionIdentifier)) { List 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 types) { foreach (EventType e in types) { RemoveSubscription(sessionIdentifier, e); } } /// /// Remove all subscriptons for a given sessionIdentifier. /// /// sessionIdentifier Id public void RemoveAllSubscriptions(string sessionIdentifier) { if (_subscriptionList.ContainsKey(sessionIdentifier)) { _subscriptionList.Remove(sessionIdentifier); } } public void AddEventHandler(Action 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); value.Cancel(); RemoveEventHandler(sessionIdentifierId); } public void FireEvent(BaseEvent bEvent) { Dictionary actionsCopy = new Dictionary(); //Copy actions list lock (_actionList) { foreach (KeyValuePair pair in _actionList) { actionsCopy.Add(pair.Key, pair.Value); } } lock (_subscriptionList) { foreach (KeyValuePair> 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 } }