public static MessageWrapper UnWrapMessage(string wrappedJsonStr)
        {
            var wrapper = Messaging <MessageWrapper> .Deserialize(wrappedJsonStr);

            return(wrapper);
        }
        // Match whatever WebSocket text is sending
        // Consistency: General rule here is that the game state if not timestamped, events may not represent the same time window.
        void HandleMessage(string message)
        {
            var msg = MessageWrapper.UnWrapMessage(message);

            // Not quite symetric, but the server is text only.
            switch (msg.type)
            {
            case "qotd":
                break;

            case "notification":
                Notification notification = Messaging <Notification> .Deserialize(message);

                gameManager.clog(notification.notificationText);
                break;

            case "register":
                GameRegister register = Messaging <GameRegister> .Deserialize(message);

                gameSession.sessionId  = register.sessionId;
                gameSession.uuidPlayer = register.uuidPlayer;
                break;

            case "gameJoin":
                GameJoin gj = Messaging <GameJoin> .Deserialize(message);

                gameManager.JoinGame(gj);
                break;

            case "scoreEvent":
                ScoreEvent se = Messaging <ScoreEvent> .Deserialize(message);

                gameManager.UpdateScore(se);
                break;

            case "moveEvent":
                MoveEvent me = Messaging <MoveEvent> .Deserialize(message);

                gameManager.UpdatePosition(me);
                break;

            case "gameState":
                GameState serverGs = Messaging <GameState> .Deserialize(message);

                gameSession.currentGs.sequence = serverGs.sequence;
                //UpdateLocalGame(serverGs);
                break;

            case "contactEvent":
                ContactEvent ce = Messaging <ContactEvent> .Deserialize(message);

                gameManager.HandleContactEvent(ce);
                break;

            case "resign":
                GameResign resign = Messaging <GameResign> .Deserialize(message);

                gameManager.theBall.SendMessage("ResetBall", null, SendMessageOptions.RequireReceiver);
                gameManager.ghostBall.SendMessage("ResetBall", null, SendMessageOptions.RequireReceiver);
                break;

            case "nextRound":
                NextRound nr = Messaging <NextRound> .Deserialize(message);

                gameManager.StartNextRound(nr);
                break;

            case "gameRestart":
                GameRestart gr = Messaging <GameRestart> .Deserialize(message);

                gameManager.RestartGame(gr);
                break;

            default:
                gameManager.clog("Unknown message arrived: " + msg.type + ", message: " + message);
                break;
            }
        }