public override void OnMessage(string message)
        {
            try
            {
                var decoded = new WebsocketChatMessage();

                // Try to decode message
                try
                {
                    decoded = JsonConvert.DeserializeObject <WebsocketChatMessage>(message);
                }
                catch (Exception e)
                {
                    Send(JsonConvert.SerializeObject(new ErrorMessage()
                    {
                        Error = "Json Invalide - " + e.Message
                    }));
                    return;
                }

                if (decoded.IsValid())
                {
                    // Update token
                    if (_playerToken == null)
                    {
                        _playerToken = new UserToken();
                    }

                    if (string.IsNullOrWhiteSpace(_playerToken.UserId))
                    {
                        try
                        {
                            _playerToken = JwtHelper.DecodeToken(decoded.UserToken);
                        }
                        catch (Exception)
                        {
                            Send(JsonConvert.SerializeObject(new ErrorMessage()
                            {
                                Error = "Token Usager Invalide"
                            }));
                            return;
                        }
                    }

                    #region Friend chat canal
                    // add client to player list
                    if (!ClientIds.ContainsKey(_playerToken.UserId))
                    {
                        ClientIds.Add(_playerToken.UserId, this);
                    }

                    // Information to create a new canal with specified user
                    if (!string.IsNullOrWhiteSpace(decoded.TargetUserHashId) && !string.IsNullOrWhiteSpace(decoded.TargetUserName))
                    {
                        // User is connected
                        if (ClientIds.ContainsKey(decoded.TargetUserHashId))
                        {
                            var otherPlayer = ClientIds[decoded.TargetUserHashId];

                            // create new chat with both users
                            var hashId = Sha1Hash.DoubleSha1Hash(BigInteger.Parse(_playerToken.UserId),
                                                                 BigInteger.Parse(decoded.TargetUserHashId));

                            if (!otherPlayer.MyCanalList.Contains(hashId))
                            {
                                otherPlayer.MyCanalList.Add(hashId);
                                otherPlayer.Send(JsonConvert.SerializeObject(new WebsocketChatMessage()
                                {
                                    CanalId   = hashId,
                                    CanalName = _playerToken.Username
                                }));
                            }

                            if (!MyCanalList.Contains(hashId))
                            {// Add canal to canal list
                                MyCanalList.Add(hashId);
                                // send to players
                                Send(JsonConvert.SerializeObject(new WebsocketChatMessage()
                                {
                                    CanalId   = hashId,
                                    CanalName = decoded.TargetUserName
                                }));
                            }
                            else
                            {
                                Send(
                                    JsonConvert.SerializeObject(new ErrorMessage()
                                {
                                    Error = "Vous êtes déjà dans le chat avec cet usager."
                                }));
                            }
                        }
                        else
                        {
                            Send(
                                JsonConvert.SerializeObject(new ErrorMessage()
                            {
                                Error = "Le joueur que vous essayez de contecter n'est pas en ligne."
                            }));
                        }
                        return;
                    }
                    #endregion

                    #region create public canal
                    // Information to create/join a new chat canal
                    var chatName = decoded.CanalName;
                    if (!string.IsNullOrWhiteSpace(chatName))
                    {
                        var hashId = Sha1Hash.GetSha1HashData(chatName);
                        if (!MyCanalList.Contains(hashId))
                        {
                            // Add canal to canal list
                            MyCanalList.Add(hashId);
                        }
                        Send(JsonConvert.SerializeObject(new WebsocketChatMessage()
                        {
                            CanalId   = hashId,
                            CanalName = chatName
                        }));
                        return;
                    }
                    #endregion

                    #region send message in canal
                    // Information to send a message to a chat canal
                    var chatId         = decoded.CanalId;
                    var messageContent = decoded.Message;
                    if (!string.IsNullOrWhiteSpace(chatId) && !string.IsNullOrWhiteSpace(messageContent))
                    {
                        if (messageContent.Length > 255)
                        {
                            Send(JsonConvert.SerializeObject(new ErrorMessage()
                            {
                                Error = "Chat trop long"
                            }));
                            return;
                        }

                        messageContent = ReplaceBadWords(messageContent);

                        var clients = Clients.Where(x => ((ChatWebsocket)x).MyCanalList.Contains(chatId)).ToList();
                        if (clients != null && clients.Count > 0)
                        {
                            if (clients.Count == 1)
                            {
                                clients[0].Send(JsonConvert.SerializeObject(new WebsocketChatMessage()
                                {
                                    Message =
                                        _playerToken.Username + " @ " +
                                        TimeHelper.CurrentCanadaTimeString() +
                                        " : (Vous êtes le seul dans ce canal) " + messageContent,
                                    CanalId = chatId
                                }));
                                return;
                            }

                            // send message to all clients who has this canal in their canal list
                            foreach (var client in clients)
                            {
                                client.Send(JsonConvert.SerializeObject(new WebsocketChatMessage()
                                {
                                    Message =
                                        _playerToken.Username + " @ " +
                                        TimeHelper.CurrentCanadaTimeString() +
                                        " : " + messageContent,
                                    CanalId = chatId
                                }));
                            }
                        }
                        return;
                    }
                    #endregion

                    #region Unregister from canal
                    // unregister from canal
                    if (!string.IsNullOrWhiteSpace(chatId))
                    {
                        if (MyCanalList.Contains(chatId))
                        {
                            MyCanalList.Remove(chatId);
                        }
                        else
                        {
                            Send(
                                JsonConvert.SerializeObject(new ErrorMessage()
                            {
                                Error = "Vous êtes déjà enregistrer à ce canal."
                            }));
                        }
                    }
                    #endregion
                    return;
                }

                Send(
                    JsonConvert.SerializeObject(new ErrorMessage()
                {
                    Error = "Format de communication invalide. Allez voir le document de communication."
                }));
            }
            catch (Exception e)
            {
                Send(JsonConvert.SerializeObject(new ErrorMessage()
                {
                    Error = e.Message
                }));
            }
        }