private async Task handleMessage(object sender, TextMessageEventArgs eventArgs) { // Update the last time we received a message from the client LastMessageTime = DateTime.Now; // Extract the event name from the message that the client sent. string eventName = JsonUtilities.DeserializeProperty <string>(eventArgs.Payload, "Event"); if (eventName == null) { Log.WriteLine("[NibriClient#{0}] Received message that didn't have an event.", Id); return; } if (!messageEventTypes.ContainsKey(eventName)) { Log.WriteLine("[NibriClient#{0}] Received message with invalid event {1}.", Id, eventName); return; } if (eventName != "CursorPosition") { Log.WriteLine("[NibriClient#{0}] Recieved message with event {1}.", Id, eventName); } try { // FUTURE: Use can reflect here to find the message type class too I think // Hall of mirrors here we come! :D Type messageType = messageEventTypes[eventName]; Type jsonNet = typeof(JsonConvert); MethodInfo deserialiserInfo = jsonNet.GetMethods().First(method => method.Name == "DeserializeObject" && method.IsGenericMethod); MethodInfo genericInfo = deserialiserInfo.MakeGenericMethod(messageType); var decodedMessage = genericInfo.Invoke(null, new object[] { eventArgs.Payload }); string handlerMethodName = "handle" + decodedMessage.GetType().Name; Type clientType = this.GetType(); MethodInfo handlerInfo = clientType.GetMethod(handlerMethodName, BindingFlags.Instance | BindingFlags.NonPublic); await(Task) handlerInfo.Invoke(this, new object[] { decodedMessage }); } catch (Exception error) { Log.WriteLine("[NibriClient#{0}] Error decoding and / or handling message.", Id); Log.WriteLine("[NibriClient#{0}] Raw frame content: {1}", Id, eventArgs.Payload); Log.WriteLine("[NibriClient#{0}] Exception details: {1}", Id, error); } }