/// <summary> /// Registers a message handler to the collection of handlers. /// </summary> /// <param name="command">The command being handled.</param> /// <param name="method">The method to invoke.</param> public static void Store(NetworkCommand command, NetworkMessageHandlerMethod method) { if (!Handlers.ContainsKey(command)) { Handlers.Add(command, method); } }
/// <summary> /// Invokes the message handler. /// </summary> public static void Invoke(NetworkMessageHandlerMethod method, NetworkMessage message, NetworkConnection connection) { if (method == null || !connection.IsConnected) { return; } SocketLog.Write(SocketLogLevel.Debug, $"Calling handler for {message.Command}"); var stopwatch = new Stopwatch(); stopwatch.Start(); var cancelSource = new CancellationTokenSource(); var token = cancelSource.Token; var task = HandlerFactory.StartNew(() => { method.Invoke(message, connection); token.ThrowIfCancellationRequested(); }, token); RunningHandlers.TryAdd(task.Id, task); try { if (!task.Wait(MaxTaskRuntime * 1000, token)) { cancelSource.Cancel(); } } catch (AggregateException ex) { foreach (var e in ex.Flatten().InnerExceptions) { SocketLog.Write(SocketLogLevel.Exception, $"Unhandled exception: {e.Message} - {e.StackTrace}"); } connection.Disconnect(); } catch (OperationCanceledException) { connection.Disconnect(); } finally { stopwatch.Stop(); RunningHandlers.TryRemove(task.Id, out var unused); cancelSource.Dispose(); Object.Destroy(message); SocketLog.Write(SocketLogLevel.Debug, $"Handler took {stopwatch.ElapsedMilliseconds}ms to complete."); } }
/// <summary> /// Tries to get a message handler from the collection. /// </summary> /// <param name="command">The message's command.</param> /// <param name="method">The handler method.</param> /// <returns></returns> public static bool TryFetch(NetworkCommand command, out NetworkMessageHandlerMethod method) { return(Handlers.TryGetValue(command, out method)); }