void Update()
    {
        int recHostId;
        int connectionId;
        int recChannelId;
        int dataSize;

        // enable play mode if needed
        if (manager && manager.IsInitialized() && !manager.IsPlayModeEnabled())
        {
            manager.EnablePlayMode(true);
        }

        // connect after broadcast discovery, if needed
        if (clientConnId < 0 && serverHost != string.Empty && serverHost != "0.0.0.0" && serverPort != 0)
        {
            Start();
        }

        try
        {
            byte error = 0;

            // disconnect if no data received for the last 10 seconds
            if (connected && (Time.time - dataReceivedAt) >= 10f)
            {
                //Debug.Log("Disconnect host " + clientHostId + ", client-conn: " + clientConnId);

                NetworkTransport.Disconnect(clientHostId, clientConnId, out error);
                dataReceivedAt = Time.time;

                if (error != (byte)NetworkError.Ok)
                {
                    throw new UnityException("Disconnect: " + (NetworkError)error);
                }
            }

            if (connected && keepAliveIndex < keepAliveCount)
            {
                if (sendKeepAlive[keepAliveIndex] && !string.IsNullOrEmpty(keepAliveData[keepAliveIndex]))
                {
                    // send keep-alive to the server
                    sendKeepAlive[keepAliveIndex] = false;
                    byte[] btSendMessage = System.Text.Encoding.UTF8.GetBytes(keepAliveData[keepAliveIndex]);

                    int compSize = 0;
                    if (compressor != null && btSendMessage.Length >= 100)
                    {
                        compSize = compressor.Compress(btSendMessage, 0, btSendMessage.Length, compressBuffer, 0);
                    }
                    else
                    {
                        System.Buffer.BlockCopy(btSendMessage, 0, compressBuffer, 0, btSendMessage.Length);
                        compSize = btSendMessage.Length;
                    }

                    NetworkTransport.Send(clientHostId, clientConnId, clientChannelId, compressBuffer, compSize, out error);
                    //Debug.Log(clientConnId + "-keep: " + keepAliveData[keepAliveIndex]);

                    if (error != (byte)NetworkError.Ok)
                    {
                        throw new UnityException("Keep-alive: " + (NetworkError)error);
                    }

                    // make sure sr-message is sent just once
                    if (keepAliveIndex == 0 && keepAliveData[0].IndexOf(",sr") >= 0)
                    {
                        RemoveResponseMsg(",sr");
                    }
                }

                keepAliveIndex++;
                if (keepAliveIndex >= keepAliveCount)
                {
                    keepAliveIndex = 0;
                }
            }

            // get next receive event
            NetworkEventType recData;

            if (serverHost != string.Empty && serverHost != "0.0.0.0" && serverPort != 0)
            {
                recData = NetworkTransport.ReceiveFromHost(clientHostId, out connectionId, out recChannelId, recBuffer, bufferSize, out dataSize, out error);
            }
            else
            {
                recData = NetworkTransport.Receive(out recHostId, out connectionId, out recChannelId, recBuffer, bufferSize, out dataSize, out error);                  // wait for broadcast
            }
            switch (recData)
            {
            case NetworkEventType.Nothing:
                break;

            case NetworkEventType.ConnectEvent:
                //Debug.Log("ConnectEvent - " + connectionId + ", client-conn: " + clientConnId);

                if (connectionId == clientConnId)
                {
                    connected = true;
                    //connectedOnce = true;

                    disconnectedAt = 0f;
                    dataReceivedAt = Time.time;
                    //sendKeepAlive = false;

                    Debug.Log("Connected.");

                    if (statusText)
                    {
                        statusText.text = "Connected.";
                    }
                }
                break;

            case NetworkEventType.DataEvent:
                //Debug.Log("DataEvent - " + connectionId + ", client-conn: " + clientConnId);
                //Debug.Log("Received " + dataSize + " bytes: " + ByteArrayToString(recBuffer, dataSize));

                if (connectionId == clientConnId)
                {
                    if (error != (byte)NetworkError.Ok)
                    {
                        Debug.Log("Receive error on connection " + connectionId + ": " + (NetworkError)error);
                    }
                    else
                    {
                        dataReceivedAt = Time.time;
                        //sendKeepAlive = true;

                        //string sRecvMessage = System.Text.Encoding.UTF8.GetString(recBuffer, 0, dataSize);
                        int decompSize = 0;
                        if (decompressor != null && (recBuffer[0] > 127 || recBuffer[0] < 32))
                        {
                            decompSize = decompressor.Decompress(recBuffer, 0, compressBuffer, 0, dataSize);
                        }
                        else
                        {
                            System.Buffer.BlockCopy(recBuffer, 0, compressBuffer, 0, dataSize);
                            decompSize = dataSize;
                        }

                        //Debug.Log("Decomp " + dataSize + " bytes to " + decompSize + " bytes.");
                        //Debug.Log("Encoded " + decompSize + " bytes: " + ByteArrayToString(compressBuffer, decompSize));

                        string sRecvMessage = decompSize > 0 ? System.Text.Encoding.UTF8.GetString(compressBuffer, 0, decompSize) : string.Empty;
                        //Debug.Log(clientConnId + "-recv: " + sRecvMessage);

//						if(sRecvMessage.StartsWith("pv"))
//						{
//							//Debug.Log("Got part face verts - " + sRecvMessage.Substring(0, 3));
//
//							// part of face-vertices msg
//							sRecvMessage = ProcessPvMessage(sRecvMessage);
//
//							if(sRecvMessage.Length == 0)
//								EnableNextKeepAlive(2);
//						}
//						else if(sRecvMessage.StartsWith("pt"))
//						{
//							//Debug.Log("Got part face tris - " + sRecvMessage.Substring(0, 3));
//
//							// part of face-triangles msg
//							sRecvMessage = ProcessPtMessage(sRecvMessage);
//
//							if(sRecvMessage.Length == 0)
//								EnableNextKeepAlive(3);
//						}

                        if (!string.IsNullOrEmpty(sRecvMessage))
                        {
                            char[]   msgDelim   = { '|' };
                            string[] asMessages = sRecvMessage.Split(msgDelim);

                            char[] partDelim = { ',' };
                            for (int i = 0; i < asMessages.Length; i++)
                            {
                                if (manager && asMessages[i].Length > 3)
                                {
                                    if (asMessages[i].StartsWith("kb,"))
                                    {
                                        //Debug.Log("Got body data");
                                        manager.SetBodyFrameData(asMessages[i]);
                                        EnableNextKeepAlive(0);
                                    }
                                    else if (asMessages[i].StartsWith("kh,"))
                                    {
                                        manager.SetBodyHandData(asMessages[i]);
                                    }
                                    else if (asMessages[i].StartsWith("km,"))
                                    {
                                        manager.SetWorldMatrixData(asMessages[i]);
                                    }
                                    else if (asMessages[i].StartsWith("vg,") && gestureManager != null)
                                    {
                                        gestureManager.SetGestureDataFromCsv(asMessages[i], partDelim);
                                    }
                                    else if (asMessages[i].StartsWith("sr,") && speechManager != null)
                                    {
                                        speechManager.SetSpeechDataFromCsv(asMessages[i], partDelim);
                                    }
                                    else if (asMessages[i].StartsWith("fp,") && faceManager != null)
                                    {
                                        //Debug.Log("Got face params");
                                        faceManager.SetFaceParamsFromCsv(asMessages[i], partDelim);
                                        //EnableNextKeepAlive(1);
                                    }
//									else if(asMessages[i].StartsWith("fv,") && faceManager != null)
//									{
//										//Debug.Log("Got face vertices");
//										faceManager.SetFaceVerticesFromCsv(asMessages[i]);
//										EnableNextKeepAlive(2);
//									}
//									else if(asMessages[i].StartsWith("fu,") && faceManager != null)
//									{
//										//Debug.Log("Got face uvs");
//										faceManager.SetFaceUvsFromCsv(asMessages[i]);
//										EnableNextKeepAlive(2);
//									}
//									else if(asMessages[i].StartsWith("ft,") && faceManager != null)
//									{
//										//Debug.Log("Got face triangles");
//										faceManager.SetFaceTrianglesFromCsv(asMessages[i]);
//
//										keepAliveData[3] = null;  // clear index 3 - one set of tris is enough
//										EnableNextKeepAlive(3);
//									}
                                }
                            }
                        }
                    }
                }
                break;

            case NetworkEventType.DisconnectEvent:
                //Debug.Log("DisconnectEvent - " + connectionId + ", client-conn: " + clientConnId);

                if (connectionId == clientConnId)
                {
                    connected = false;
                    //connectedOnce = true;  // anyway, try to reconnect

                    disconnectedAt = Time.time;
                    dataReceivedAt = 0f;
                    //sendKeepAlive = false;

                    Debug.Log("Disconnected: " + (NetworkError)error);

                    if (error != (byte)NetworkError.Ok)
                    {
                        throw new UnityException("Disconnected: " + (NetworkError)error);
                    }
                }
                break;

            case NetworkEventType.BroadcastEvent:
                //Debug.Log("BroadcastEvent - " + connectionId + ", client-conn: " + clientConnId);

                int receivedSize;
                NetworkTransport.GetBroadcastConnectionMessage(bcastHostId, bcastBuffer, bcastBuffer.Length, out receivedSize, out error);

                string senderAddr;
                int    senderPort;
                NetworkTransport.GetBroadcastConnectionInfo(bcastHostId, out senderAddr, out senderPort, out error);

                if (serverHost == string.Empty || serverHost == "0.0.0.0" || serverPort == 0)
                {
                    string sData = System.Text.Encoding.UTF8.GetString(bcastBuffer, 0, bcastBuffer.Length).Trim();
                    OnReceivedBroadcast(senderAddr, sData);
                }
                break;
            }

            // try to reconnect, if disconnected
            if (!connected && /**connectedOnce &&*/ disconnectedAt > 0f && (Time.time - disconnectedAt) >= reconnectAfter)
            {
                disconnectedAt = 0f;

                error        = 0;
                clientConnId = NetworkTransport.Connect(clientHostId, serverHost, serverPort, 0, out error);

                if (error == (byte)NetworkError.Ok)
                {
                    Debug.Log("Reconnecting to the server - " + serverHost + ":" + serverPort);

                    if (statusText)
                    {
                        statusText.text = "Reconnecting to the server...";
                    }
                }
                else
                {
                    throw new UnityException("Error while reconnecting: " + (NetworkError)error);
                }
            }
        }
        catch (System.Exception ex)
        {
            Debug.LogError(ex.Message + "\n" + ex.StackTrace);

            if (statusText)
            {
                statusText.text = ex.Message;
            }
        }
    }