internal void OnTrackerRegistryFinished(NetworkMessage netMsg)
        {
            // parse message
            ViveTrackerRegistryReturnMsg msg = netMsg.ReadMessage <ViveTrackerRegistryReturnMsg>();

            // assign client id
            clientId = msg.clientId;

            // attach sync pose obj to main camera
            ViveShare_SyncIdentity syncId = Camera.main.gameObject.AddComponent <ViveShare_SyncIdentity>();

            syncId.id           = msg.syncObjName;
            syncId.hasAuthority = false;
            syncId.Register();

            ViveShare_SyncPose syncPose = Camera.main.gameObject.AddComponent <ViveShare_SyncPose>();

            ViveShare_Log.LogInfo(logLevel, "[ViveShare_Client] Client id (" + clientId + ") assigned");
            ViveShare_Log.LogInfo(logLevel, "[ViveShare_Client] Tracker registry (" + msg.syncObjName + ") finished");

            state = ViveNetworkState.Wait_Ready;

            // invoke callbacks --  we only think the connection is established at this moment
            ViveShare_Event.client_connectSuccessEvent.Invoke();
        }
        private void DisconnectInternal()
        {
            // detect connection time out
            if (state == ViveNetworkState.Wait_Connect || state == ViveNetworkState.Wait_TrackerRegistry)
            {
                ViveShare_Log.LogError(logLevel, "[ViveShare_Client] Disconnect due to connection timeout");
                ViveShare_Event.client_connectFailedEvent.Invoke();
            }

            ViveShare_Log.LogInfo(logLevel, "[ViveShare_Client] Disconnect");

            // reset and remove resources
            if (needTrackerPose)
            {
                ViveShare_SyncPose syncPose = Camera.main.gameObject.GetComponent <ViveShare_SyncPose>();
                if (syncPose != null)
                {
                    Destroy(syncPose);
                }

                ViveShare_SyncIdentity syncId = Camera.main.gameObject.GetComponent <ViveShare_SyncIdentity>();
                if (syncId != null)
                {
                    Destroy(syncId);
                }
            }

            clientId = -1;

            ViveShare_Event.client_disconnectEvent.Invoke();

            state = ViveNetworkState.Init;
        }