/// <summary>
        /// create an Rtm Client instance
        /// The Agora RTM SDK supports creating multiple RtmClient instances.
        /// All methods in the RtmClient class are executed asynchronously.
        /// </summary>
        /// <param name="appId">
        /// The App ID issued to you from the Agora Console. Apply for a new App ID from Agora if it is missing from your kit.
        /// </param>
        /// <param name="eventHandler">
        /// An RtmClientListener object that reports to the app on RTM SDK runtime events.
        /// </param>
        public RtmClient(string appId, RtmClientEventHandler eventHandler)
        {
            if (appId == null || eventHandler == null)
            {
                Debug.LogError("appId or eventHandler is null");
                return;
            }
            AgoraCallbackObject.GetInstance();
            _rtmServicePtr = createRtmService_();
            _eventHandler  = eventHandler;
            int ret = initialize(_rtmServicePtr, appId, eventHandler.GetRtmClientEventHandlerPtr());

            if (ret != 0)
            {
                Debug.LogError("RtmClient create fail, error:  " + ret);
            }
        }
        /// <summary>
        /// Releases all resources used by the RtmClient instance.
        /// Note: Do not call this method in any of your callbacks.
        /// </summary>
        /// <param name="sync">
        /// wheather release rtm client async.
        /// </param>
        private void Release(bool sync)
        {
            Debug.Log("RtmClient Release");
            if (_rtmServicePtr == IntPtr.Zero)
            {
                Debug.LogError("rtmServicePtr is null");
                return;
            }

            foreach (KeyValuePair <string, RtmChannel> item in channelDic)
            {
                RtmChannel channel = item.Value;
                if (channel != null)
                {
                    channel.Dispose();
                }
            }
            channelDic.Clear();
            channelDic = null;

            foreach (RtmChannelAttribute item in attributeList)
            {
                if (item != null)
                {
                    item.Dispose();
                }
            }
            attributeList.Clear();
            attributeList = null;

            if (_rtmCallManager != null)
            {
                _rtmCallManager.Dispose();
                _rtmCallManager = null;
            }

            release(_rtmServicePtr, sync);
            _rtmServicePtr = IntPtr.Zero;
            _eventHandler.Release();
            _eventHandler = null;
        }