private static unsafe void Receive()
        {
            // Receive anything sent to us
            // Similar setup for sending data
            MessageHeader *header = (MessageHeader *)receiveStream.BufferRead->Buffer;

            int bytesNeeded = 0;

            if (receiveStream.TotalBytes < sizeof(MessageHeader))
            {
                bytesNeeded = sizeof(MessageHeader) - receiveStream.TotalBytes;
            }
            else
            {
                bytesNeeded = sizeof(MessageHeader) + header->bytes - receiveStream.TotalBytes;
            }

            while (bytesNeeded > 0)
            {
                MessageStream.MessageStreamBuffer *bufferWrite = receiveStream.BufferWrite;

                int bytesAvail = bufferWrite->Capacity - bufferWrite->Size;
#if UNITY_WEBGL
                uint actualWritten = WebSocketReceive(bufferWrite->Buffer + bufferWrite->Size,
                                                      bytesNeeded <= bytesAvail ? bytesNeeded : bytesAvail);
                if (actualWritten == 0xffffffff)
#else
                uint actualWritten = Baselib_Socket_TCP_Recv(hSocket, bufferWrite->Buffer + bufferWrite->Size,
                                                             (uint)(bytesNeeded <= bytesAvail ? bytesNeeded : bytesAvail), (Baselib_ErrorState *)UnsafeUtility.AddressOf(ref errState));
                if (errState.code != Baselib_ErrorCode.Success)
#endif
                {
                    // Something bad happened; lost connection maybe?
                    // After cleaning up, next time we will try to re-initialize
                    Disconnect();
                    initRetryCounter = kInitRetryCounter;
                    return;
                }

                if (bytesNeeded > 0 && actualWritten == 0)
                {
                    // Don't do anything with data until we've received everything
                    return;
                }

                receiveStream.UpdateSize((int)actualWritten);
                bytesNeeded -= (int)actualWritten;
                if (bytesNeeded == 0)
                {
                    // Finished receiving header
                    if (receiveStream.TotalBytes == sizeof(MessageHeader))
                    {
                        // De-synced somewhere... reset connection
                        if (header->magicId != EditorMessageIds.kMagicNumber)
                        {
                            Disconnect();
                            initRetryCounter = kInitRetryCounter;
                            return;
                        }
                        bytesNeeded = header->bytes;
                        receiveStream.Allocate(bytesNeeded);
                    }

                    // Finished receiving message
                    if (bytesNeeded == 0)
                    {
                        // Otherwise bytesNeeded becomes 0 after message is finished, which can be immediately in the
                        // case of PlayerMessageId.kApplicationQuit (message size 0)
                        foreach (var e in m_EventMessageList)
                        {
                            if (e.messageId == header->messageId)
                            {
                                // This could be anything from a 4-byte "bool" to an asset sent from the editor
                                byte[] messageData = receiveStream.ToByteArray(sizeof(MessageHeader), receiveStream.TotalBytes);
                                e.Invoke(0, messageData);
                            }
                        }

                        if (header->messageId == EditorMessageIds.kApplicationQuit)
                        {
                            UnityEngine.Debug.Log("Unity editor has been closed");
                            Disconnect();
                        }

                        if (header->messageId == EditorMessageIds.kNoFurtherConnections)
                        {
                            UnityEngine.Debug.Log("Unity editor can not accept any more connections");
                            Disconnect();
                        }

                        // Poll for next message
                        receiveStream.RecycleStreamAndFreeExtra();
                        bytesNeeded = sizeof(MessageHeader);
                    }
                }
            }

            // This code should not be executable
            throw new InvalidOperationException("Internal error receiving network data");
        }