public void RetrieveQueueStateless()
            {
                while (!statelessQueue.IsEmpty)
                {
                    if (!IsMessageQueueRunning)
                    {
                        continue;
                    }

                    byte[] message;
                    if (statelessQueue.TryDequeue(out message))
                    {
                        var stream = new MemoryStream(message);
                        var reader = new EndiannessBinaryReader(stream);
                        try
                        {
                            messageDelegate(reader);
                        }
                        catch (Exception e)
                        {
                            OrLogWarn(LogLevel.Info, "error: " + e.Message);
                            OrLogWarn(LogLevel.Verbose, "stacktrace: " + e.StackTrace);
                        }
                        finally
                        {
                            reader.Close();
                            stream.Close();
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }
            public IEnumerator GetRoomProperties(RoomInfo room)
            {
                OrLog(LogLevel.Verbose, "Get room properties start");
                UnityWebRequest webRequest = UnityWebRequest.Get(BASE_URL + _serverAddress + ":" + _entryPort + "/room/prop/" + room.Name);

                webRequest.SetRequestHeader("User-Agent", UA_UNITY_CDK);
                yield return(webRequest.SendWebRequest());

                if (webRequest.isNetworkError)
                {
                    OrLogError(LogLevel.Info, webRequest.error);
                    // TODO VERSION ERROR HANDLE CALLBACK
                    OrLogError(LogLevel.Info, "get room properties failed. http status code:" + webRequest.responseCode);

                    yield break;
                }

                var streamReader  = new MemoryStream(webRequest.downloadHandler.data);
                var messageReader = new EndiannessBinaryReader(streamReader);

                if (webRequest.responseCode != 200)
                {
                    OrLog(LogLevel.Verbose, "get room properties failed. http status code:" + webRequest.responseCode);

                    yield break;
                }

                var responseCode = (ResponseCode)messageReader.ReadUInt16();
                var contentLen   = messageReader.ReadUInt16();

                if (0 < contentLen)
                {
                    var content = messageReader.ReadBytes(contentLen);
                    UpdateHashtable(content, null, room.Properties);
                }

                OrLog(LogLevel.Verbose, "Get room properties end");
            }
        private static void HandleMessage(EndiannessBinaryReader message)
        {
            // TODO fix provisional logics.
            //if (!_roomJoining || !_roomJoined) return;

            var headerSize  = Marshal.SizeOf(typeof(Header));
            var headerBytes = message.ReadBytes(headerSize);

            OrLog(LogLevel.VeryVerbose, "raw header:" + BitConverter.ToString(headerBytes));
            var    ptr = Marshal.AllocCoTaskMem(headerSize);
            var    gch = GCHandle.Alloc(headerBytes, GCHandleType.Pinned);
            Header header;

            try
            {
                header = Marshal.PtrToStructure <Header>(gch.AddrOfPinnedObject());
            }
            catch (Exception e)
            {
                OrLogError(LogLevel.Info, "handle error: " + e.Message);
                OrLogError(LogLevel.Verbose, "stacktrace: " + e.StackTrace);
                gch.Free();

                return;
            }
            gch.Free();

            PlayerId[] destsPids = new PlayerId[header.DestLen];
            byte[]     content   = null;
            if (header.DestLen > 0)
            {
                var destsBytes = message.ReadBytes(sizeof(PlayerId) * header.DestLen);
                Buffer.BlockCopy(destsBytes, 0, destsPids, 0, sizeof(PlayerId) * header.DestLen);
            }

            // TODO fix provisional logics.
            if ((RelayCode)header.RelayCode != RelayCode.JOIN && !(_roomJoined || _PropertiesInitializing))
            {
                return;
            }

            switch ((RelayCode)header.RelayCode)
            {
            case RelayCode.JOIN:
                var alignmentLen = (UInt16)0;
                var alignment    = new byte[] { };
                OrLog(LogLevel.Verbose, "HandleMessage RelayCode.JOIN");
                var assginPid = (PlayerId)message.ReadUInt16();
                OrLog(LogLevel.Verbose, "read bytes assginPid:" + assginPid.ToString());
                var masterPid = (PlayerId)message.ReadUInt16();
                OrLog(LogLevel.Verbose, "read bytes masterPid:" + masterPid.ToString());
                var seedLen = message.ReadUInt16();
                OrLog(LogLevel.Verbose, "read bytes seedLen:" + seedLen.ToString());
                var nameLen = message.ReadUInt16();
                OrLog(LogLevel.Verbose, "read bytes nameLen:" + nameLen.ToString());

                var joinSeedByte = message.ReadBytes(seedLen);

                if (seedLen > 0)
                {
                    alignmentLen = (UInt16)(seedLen % 4);
                    if (alignmentLen > 0)
                    {
                        message.ReadBytes(alignmentLen);
                    }
                }
                byte[] nameBytes = null;
                if (nameLen > 0)
                {
                    nameBytes = new byte[nameLen];
                    nameBytes = message.ReadBytes(nameLen);
                }

                OrLog(LogLevel.Verbose, "joinGuid Compare:" + BitConverter.ToString(joinSeedByte) + " : " + BitConverter.ToString(dealerListener.JoinGuid));
                if (BitConverter.ToString(joinSeedByte) != BitConverter.ToString(dealerListener.JoinGuid) && _roomJoined)
                {
                    var otherPlayer = new UserSession(header.SrcPid, header.SrcOid, false, header.SrcPid == masterPid);
                    if (nameLen > 0)
                    {
                        OrLog(LogLevel.Verbose, "receive name bytes: " + BitConverter.ToString(nameBytes));
                        otherPlayer.NickName = Encoding.UTF8.GetString(nameBytes);    // TODO use Unicode(UTF-16) here?
                    }
                    if (header.SrcPid == masterPid)
                    {
                        _masterClient = otherPlayer;
                    }

                    _players.Add(otherPlayer);
                    OrLog(LogLevel.Verbose, "OnOpenRelayPlayerConnectedCall :" + otherPlayer.ID.ToString());
                    OnOpenRelayPlayerConnectedCall(otherPlayer);
                }

                break;

            case RelayCode.LEAVE:
                OrLog(LogLevel.Verbose, "HandleMessage RelayCode.LEAVE");
                var newMasterPid = (PlayerId)message.ReadUInt16();
                if (header.SrcPid == Player.ID)
                {
                    OrLog(LogLevel.Verbose, "player left :" + header.SrcPid.ToString());
                    _leaveComplete = true;
                }
                else
                {
                    OrLog(LogLevel.Verbose, "other player left :" + header.SrcPid.ToString());
                    UserSession otherPlayer = null;
                    foreach (var p in _players)
                    {
                        if ((PlayerId)p.ID == header.SrcPid)
                        {
                            otherPlayer = p;
                            _players.Remove(otherPlayer);
                            break;
                        }
                    }
                    if (newMasterPid > 0)
                    {
                        _masterClient.IsMasterClient = false;
                        foreach (var p in _players)
                        {
                            if (newMasterPid == p.ID)
                            {
                                p.IsMasterClient = true;
                                _masterClient    = p;
                                break;
                            }
                        }
                    }
                    if (otherPlayer != null)
                    {
                        OrLog(LogLevel.Verbose, "player :" + otherPlayer.ID);
                        OnOpenRelayPlayerDisconnectedCall(otherPlayer);
                    }
                }

                break;

            case RelayCode.RELAY:
                if (!_roomJoined)
                {
                    return;
                }
                OrLog(LogLevel.VeryVerbose, "HandleMessage RelayCode.RELAY");
                switch ((DestinationCode)header.DestCode)
                {
                case DestinationCode.StrictBroadcast:

                    break;

                case DestinationCode.Broadcast:
                    if (header.SrcPid == _player.ID)
                    {
                        return;                                     //ignore
                    }
                    break;

                case DestinationCode.Exclude:
                    if (destsPids.Contains <PlayerId>((PlayerId)_player.ID))
                    {
                        return;                                                            //ignore
                    }
                    // exclude case
                    break;

                case DestinationCode.Include:
                    if (!destsPids.Contains <PlayerId>((PlayerId)_player.ID))
                    {
                        return;                                                             //ignore
                    }
                    // include case
                    break;

                case DestinationCode.MasterOnly:
                    if (isMasterClient)
                    {
                        break;
                    }

                    return;

                default:

                    return;        //default is ignore
                }
                content = message.ReadBytes(header.ContentLen);
                OrLog(LogLevel.Verbose, "OnEventCall from:" + header.SrcPid.ToString() + " - " + header.SrcOid.ToString() + " DestCode:" + header.DestCode.ToString() + " destsPids:" + destsPids.Length.ToString());
                if (_players.Any(x => x.ID == header.SrcPid))
                {
                    OnSyncCall((byte)header.ContentCode, content, header.SrcPid, header.SrcOid);
                }
                else
                {
                    OrLog(LogLevel.Verbose, "PlayerId: " + header.SrcPid + " addn't yet.");
                }

                break;

            case RelayCode.RELAY_STREAM:
                if (!_roomJoined)
                {
                    return;
                }
                OrLog(LogLevel.VeryVerbose, "HandleMessage RelayCode.RELAY_STREAM");

                switch ((DestinationCode)header.DestCode)
                {
                case DestinationCode.StrictBroadcast:

                    break;

                case DestinationCode.Broadcast:
                    if (header.SrcPid == _player.ID)
                    {
                        return;                                     //ignore
                    }
                    break;

                case DestinationCode.Exclude:
                    if (header.SrcPid == _player.ID)
                    {
                        return;                                     //ignore
                    }
                    if (destsPids.Contains <PlayerId>((PlayerId)_player.ID))
                    {
                        return;                                                            //ignore
                    }
                    // exclude case
                    break;

                case DestinationCode.Include:
                    if (header.SrcPid == _player.ID)
                    {
                        return;                                     //ignore
                    }
                    if (!destsPids.Contains <PlayerId>((PlayerId)_player.ID))
                    {
                        return;                                                             //ignore
                    }
                    // include case
                    break;

                case DestinationCode.MasterOnly:
                    if (isMasterClient)
                    {
                        break;
                    }

                    return;

                default:

                    return;        //default is ignore
                }
                content = message.ReadBytes(header.ContentLen);
                OrLog(LogLevel.VeryVerbose, "OnSyncVoiceCall from:" + header.SrcPid.ToString() + " - " + header.SrcOid.ToString() + " DestCode:" + header.DestCode.ToString() + " destsPids:" + destsPids.Length.ToString());
                //if (_player != null && _players != null && _players.Count > 0 && _players.Any(x => x.ID == header.SrcPid)) OnSyncVoiceCall((byte)header.ContentCode, content, header.SrcPid, header.SrcOid);
                //else OrLog(LogLevel.Verbose, "PlayerId: " + header.SrcPid + " addn't yet.");
                OnSyncStreamCall((byte)header.ContentCode, content, header.SrcPid, header.SrcOid);

                break;

            case RelayCode.UNITY_CDK_RELAY:
                if (!_roomJoined)
                {
                    return;
                }
                OrLog(LogLevel.VeryVerbose, "HandleMessage RelayCode.UNITY_CDK_RELAY");
                switch ((DestinationCode)header.DestCode)
                {
                case DestinationCode.StrictBroadcast:

                    break;

                case DestinationCode.Broadcast:
                    if (header.SrcPid == _player.ID)
                    {
                        return;                                     //ignore
                    }
                    break;

                case DestinationCode.Exclude:
                    if (destsPids.Contains <PlayerId>((PlayerId)_player.ID))
                    {
                        return;                                                            //ignore
                    }
                    // exclude case
                    break;

                case DestinationCode.Include:
                    if (!destsPids.Contains <PlayerId>((PlayerId)_player.ID))
                    {
                        return;                                                             //ignore
                    }
                    // include case
                    break;

                case DestinationCode.MasterOnly:
                    if (isMasterClient)
                    {
                        break;
                    }

                    return;

                default:

                    return;        //default is ignore
                }
                content = message.ReadBytes(header.ContentLen);
                OrLog(LogLevel.Verbose, "OnEventCall from:" + header.SrcPid.ToString() + " - " + header.SrcOid.ToString() + " DestCode:" + header.DestCode.ToString() + " destsPids:" + destsPids.Length.ToString());
                if (_players.Any(x => x.ID == header.SrcPid))
                {
                    OnSyncPlatformCall((byte)header.ContentCode, content, header.SrcPid, header.SrcOid);
                }
                else
                {
                    OrLog(LogLevel.Verbose, "PlayerId: " + header.SrcPid + " addn't yet.");
                }

                break;

            case RelayCode.TIMEOUT:
                OrLog(LogLevel.Verbose, "HandleMessage RelayCode.TIMEOUT");
                //timeout leave

                break;

            case RelayCode.REJOIN:
                OrLog(LogLevel.Verbose, "HandleMessage RelayCode.REJOIN");
                //re join

                break;

            case RelayCode.SET_LEGACY_MAP:
                OrLog(LogLevel.Verbose, "HandleMessage RelayCode.SET_LEGACY_MAP");
                var keysBytesLen = message.ReadUInt16();
                alignmentLen = (UInt16)(keysBytesLen % 4);
                var contentBytesLen = message.ReadUInt16();
                var keysBytes       = message.ReadBytes(keysBytesLen);
                if (alignmentLen > 0)
                {
                    message.ReadBytes(alignmentLen);
                }
                content = message.ReadBytes(contentBytesLen);
                UpdateHashtable(content, keysBytes, _room.Properties);
                OnOpenRelayRoomPropertiesChangedCall(_room.Properties);
                if (_PropertiesInitializing)
                {
                    _PropertiesInitializing = false;
                    _PropertiesReady        = true;
                }

                break;

            case RelayCode.GET_LEGACY_MAP:
                OrLog(LogLevel.Verbose, "HandleMessage RelayCode.GET_LEGACY_MAP");
                if (header.ContentLen > 0)
                {
                    content = message.ReadBytes(header.ContentLen);
                    UpdateHashtable(content, null, _room.Properties);
                }
                if (_PropertiesInitializing)
                {
                    _PropertiesInitializing = false;
                    _PropertiesReady        = true;
                }

                break;

            case RelayCode.GET_USERS:
                OrLog(LogLevel.Verbose, "HandleMessage RelayCode.GET_USERS");
                //get users responce

                break;

            case RelayCode.SET_MASTER:
                OrLog(LogLevel.Verbose, "HandleMessage RelayCode.SET_MASTER");
                var setMasterPid = (PlayerId)message.ReadUInt16();
                _masterClient.IsMasterClient = false;
                if (setMasterPid == Player.ID)
                {
                    _player.IsMasterClient = true;
                    _masterClient          = _player;
                }
                else
                {
                    foreach (var p in _players)
                    {
                        if (setMasterPid == p.ID)
                        {
                            p.IsMasterClient = true;
                            _masterClient    = p;
                            break;
                        }
                    }
                }

                break;

            case RelayCode.GET_MASTER:
                OrLog(LogLevel.Verbose, "HandleMessage RelayCode.GET_MASTER");
                var getMasterPid = (PlayerId)message.ReadUInt16();
                _masterClient.IsMasterClient = false;
                foreach (var p in _players)
                {
                    if (getMasterPid == p.ID)
                    {
                        p.IsMasterClient = true;
                        _masterClient    = p;
                        break;
                    }
                }

                break;

            case RelayCode.GET_SERVER_TIMESTAMP:
                OrLog(LogLevel.Verbose, "HandleMessage RelayCode.GET_SERVER_TIMESTAMP");
                //get server timestamp responce
                var timestamp = (UInt16)message.ReadUInt16();
                // TODO set server timestamp logic.

                break;

            case RelayCode.RELAY_LATEST:
                if (!_roomJoined)
                {
                    return;
                }
                OrLog(LogLevel.Verbose, "HandleMessage RelayCode.RELAY_LATEST");

                content = message.ReadBytes(header.ContentLen);
                OrLog(LogLevel.Verbose, "OnEventCall from:" + header.SrcPid.ToString() + " - " + header.SrcOid.ToString() + " DestCode:" + header.DestCode.ToString() + " destsPids:" + destsPids.Length.ToString());
                if (_players.Any(x => x.ID == header.SrcPid))
                {
                    OnSyncLatestCall((byte)header.ContentCode, content, header.SrcPid, header.SrcOid);
                }
                else
                {
                    OrLog(LogLevel.Verbose, "PlayerId: " + header.SrcPid + " addn't yet.");
                }

                break;

            case RelayCode.GET_LATEST:
                if (!_roomJoined || header.SrcPid != _player.ID)
                {
                    return;
                }
                OrLog(LogLevel.Verbose, "HandleMessage RelayCode.GET_LATEST");

                content = message.ReadBytes(header.ContentLen);
                OrLog(LogLevel.Verbose, "OnEventCall from:" + header.SrcPid.ToString() + " - " + header.SrcOid.ToString() + " DestCode:" + header.DestCode.ToString() + " destsPids:" + destsPids.Length.ToString());
                //if (_player.ID == header.SrcPid) OnRelayEventCall((byte)header.ContentCode, content, header.SrcPid, header.SrcOid);

                break;

            case RelayCode.UNITY_CDK_RELAY_LATEST:
                if (!_roomJoined)
                {
                    return;
                }
                OrLog(LogLevel.Verbose, "HandleMessage RelayCode.UNITY_CDK_RELAY_LATEST");

                content = message.ReadBytes(header.ContentLen);
                OrLog(LogLevel.Verbose, "OnEventCall from:" + header.SrcPid.ToString() + " - " + header.SrcOid.ToString() + " DestCode:" + header.DestCode.ToString() + " destsPids:" + destsPids.Length.ToString());
                if (_players.Any(x => x.ID == header.SrcPid))
                {
                    OnSyncLatestPlatformCall((byte)header.ContentCode, content, header.SrcPid, header.SrcOid);
                }
                else
                {
                    OrLog(LogLevel.Verbose, "PlayerId: " + header.SrcPid + " addn't yet.");
                }

                break;

            case RelayCode.UNITY_CDK_GET_LATEST:
                if (!_roomJoined || header.SrcPid != _player.ID)
                {
                    return;
                }
                OrLog(LogLevel.Verbose, "HandleMessage RelayCode.UNITY_CDK_GET_LATEST");

                content = message.ReadBytes(header.ContentLen);
                OrLog(LogLevel.Verbose, "OnEventCall from:" + header.SrcPid.ToString() + " - " + header.SrcOid.ToString() + " DestCode:" + header.DestCode.ToString() + " destsPids:" + destsPids.Length.ToString());
                //if (_player.ID == header.SrcPid) OnRelayEventCall((byte)header.ContentCode, content, header.SrcPid, header.SrcOid);
                //else OrLog(LogLevel.Verbose, "other target PlayerId: " + header.SrcPid);

                break;

            case RelayCode.SET_LOBBY_MAP:
                OrLog(LogLevel.Verbose, "HandleMessage RelayCode.SET_LEGACY_MAP");
                content = message.ReadBytes(header.ContentLen);
                //_room.Properties = ToHash(content);
                //OnOpenRelayRoomPropertiesChangedCall(ToHash(content));
                //_PropertiesInitialized = true;

                break;

            case RelayCode.GET_LOBBY_MAP:
                OrLog(LogLevel.Verbose, "HandleMessage RelayCode.GET_LEGACY_MAP");
                content = message.ReadBytes(header.ContentLen);
                //_room.Properties = ToHash(content);
                //_PropertiesInitialized = true;

                break;

            case RelayCode.SET_MASK:
                OrLog(LogLevel.Verbose, "HandleMessage RelayCode.SET_MASK");

                break;

            case RelayCode.GET_MASK:
                OrLog(LogLevel.Verbose, "HandleMessage RelayCode.GET_MASK");

                break;

            case RelayCode.REPLAY_JOIN:
                OrLog(LogLevel.Verbose, "HandleMessage RelayCode.REPLAY_JOIN");

                break;

            case RelayCode.LOAD_PLAYER:
                OrLog(LogLevel.Verbose, "HandleMessage RelayCode.LOAD_PLAYER");
                var total           = message.ReadByte();
                var position        = message.ReadByte();
                var nameContainsMax = (UInt16)message.ReadUInt16();
                message.ReadByte();     // 4byte alignment
                var names = new List <string>();
                for (int count = 0; count < nameContainsMax; count++)
                {
                    var nameSize = (UInt16)message.ReadUInt16();
                    var name     = message.ReadBytes(nameSize);
                    names.Add(Encoding.UTF8.GetString(name));
                    alignmentLen = (UInt16)(nameSize % 4);
                    if (alignmentLen > 0)
                    {
                        message.ReadBytes(alignmentLen);
                    }
                }

                break;

            default:
                OrLogError(LogLevel.Verbose, "HandleMessage error: RelayCode not match, invalid case:" + (RelayCode)header.RelayCode);

                break;
            }
        }
            private IEnumerator CreateRoom(string roomName, UInt16 maxPlayer, RoomOptions presetRoomOptions, bool ignoreExist)
            {
                createAndJoinRoomAbort = false;
                OrLog(LogLevel.Verbose, "room name: " + roomName);
                OrLog(LogLevel.Verbose, "room max player: " + maxPlayer);
                var messageBytes = new byte[sizeof(UInt16)];
                var stream       = new MemoryStream(messageBytes);
                var message      = new EndiannessBinaryWriter(stream);

                try
                {
                    message.Write(maxPlayer);
                }
                catch (Exception e)
                {
                    OrLogError(LogLevel.Info, "error: " + e.Message);
                    OrLogError(LogLevel.Verbose, "stacktrace: " + e.StackTrace);
                }
                message.Close();

                UnityWebRequest webRequest = UnityWebRequest.Put(BASE_URL + _serverAddress + ":" + _entryPort + "/room/create/" + roomName, messageBytes);

                webRequest.method = "POST";
                webRequest.SetRequestHeader("User-Agent", UA_UNITY_CDK);
                webRequest.SetRequestHeader("Content-Type", "application/octet-stream");
                //webRequest.SetRequestHeader("Content-Length", messageBytes.Length.ToString()); // auto setting.
                yield return(webRequest.SendWebRequest());

                if (webRequest.isNetworkError)
                {
                    OrLogError(LogLevel.Info, webRequest.error);
                    OnOpenRelayCreateRoomFailedCall((short)webRequest.responseCode, "failed polling");//TODO error handle case;
                    yield break;
                }

                var streamReader  = new MemoryStream(webRequest.downloadHandler.data);
                var messageReader = new EndiannessBinaryReader(streamReader);

                if (webRequest.responseCode != 200)
                {
                    OrLog(LogLevel.Verbose, "post create room failed. http status code:" + webRequest.responseCode);
                    OnOpenRelayCreateRoomFailedCall((short)webRequest.responseCode, " failed polling");

                    yield break;
                }

                var responseCode = (ResponseCode)messageReader.ReadUInt16();

                OrLog(LogLevel.Verbose, "read bytes responseCode:" + responseCode.ToString());
                messageReader.ReadUInt16();// read alignment

                if (ignoreExist && responseCode == ResponseCode.OPENRELAY_RESPONSE_CODE_NG_CREATE_ROOM_ALREADY_EXISTS)
                {
                    OrLog(LogLevel.Verbose, "ResponseCode.OPENRELAY_RESPONSE_CODE_NG_CREATE_ROOM_ALREADY_EXISTS, but ignore ");
                }
                else if (!ignoreExist && responseCode == ResponseCode.OPENRELAY_RESPONSE_CODE_NG_CREATE_ROOM_ALREADY_EXISTS)
                {
                    createAndJoinRoomAbort = true;
                    OrLogError(LogLevel.Info, "post create room failed. http status code:" + webRequest.responseCode);
                    OrLogError(LogLevel.Info, "post create room failed. response code:" + responseCode);
                    OnOpenRelayCreateRoomFailedCall((short)webRequest.responseCode, " failed polling");

                    yield break;
                }
                else if (responseCode != ResponseCode.OPENRELAY_RESPONSE_CODE_OK_ROOM_ASSGIN_AND_CREATED)
                {
                    OrLogError(LogLevel.Info, "post create room failed. http status code:" + webRequest.responseCode);
                    OrLogError(LogLevel.Info, "post create room failed. response code:" + responseCode);
                    OnOpenRelayCreateRoomFailedCall((short)webRequest.responseCode, " failed polling");

                    yield break;
                }

                var responseSize  = Marshal.SizeOf(typeof(RoomResponse));
                var responseBytes = messageReader.ReadBytes(responseSize);

                OrLog(LogLevel.VeryVerbose, "raw response:" + BitConverter.ToString(responseBytes));
                var          ptr = Marshal.AllocCoTaskMem(responseSize);
                var          gch = GCHandle.Alloc(responseBytes, GCHandleType.Pinned);
                RoomResponse response;

                try
                {
                    response = Marshal.PtrToStructure <RoomResponse>(gch.AddrOfPinnedObject());
                    OrLog(LogLevel.Verbose, "read bytes created room Id:" + BitConverter.ToString(response.Id));
                    OrLog(LogLevel.Verbose, "read bytes created room Capacity:" + response.Capacity.ToString());
                    OrLog(LogLevel.Verbose, "read bytes created room StfDealPort:" + response.StfDealPort.ToString());
                    OrLog(LogLevel.Verbose, "read bytes created room StfSubPort:" + response.StfSubPort.ToString());
                    OrLog(LogLevel.Verbose, "read bytes created room StlDealPort:" + response.StlDealPort.ToString());
                    OrLog(LogLevel.Verbose, "read bytes created room StlSubPort:" + response.StlSubPort.ToString());
                    OrLog(LogLevel.Verbose, "read bytes created room QueuingPolicy:" + response.QueuingPolicy.ToString());
                    OrLog(LogLevel.Verbose, "read bytes created room Flags:" + response.Flags.ToString());
                    OrLog(LogLevel.Verbose, "read bytes created room NameLen:" + response.NameLen.ToString());
                    OrLog(LogLevel.Verbose, "read bytes created room FilterLen:" + response.FilterLen.ToString());
                }
                catch (Exception e)
                {
                    OrLogError(LogLevel.Info, "handle error: " + e.Message);
                    OrLogError(LogLevel.Verbose, "stacktrace: " + e.StackTrace);
                    OrLogError(LogLevel.Verbose, "post create room failed ");
                    gch.Free();

                    yield break;
                }
                gch.Free();

                //if (0 < response.NameLen)
                //{
                var name = messageReader.ReadBytes(256);

                OrLog(LogLevel.Verbose, "read bytes created room Name:" + Encoding.UTF8.GetString(name));
                //}
                //if (0 < response.FilterLen)
                //{
                var filter = messageReader.ReadBytes(256);

                OrLog(LogLevel.Verbose, "read bytes created room Filter:" + BitConverter.ToString(filter));
                //}
                var listenMode = messageReader.ReadByte();

                OrLog(LogLevel.Verbose, "read bytes get room listen mode:" + listenMode);
                messageReader.ReadBytes(3); // alignment 3bytes for 4byte alignment.
                var ipv4Bytes = messageReader.ReadBytes(4);
                var ipv4Addr  = new IPAddress(ipv4Bytes).ToString();

                //var ipv4Addr = _settings.ServerAddress; // TODO ISSUE 24 provisional fix
                OrLog(LogLevel.Verbose, "read bytes get room listen ipv4 addr:" + ipv4Addr);
                var ipv6Bytes = messageReader.ReadBytes(16);
                var ipv6Addr  = new IPAddress(ipv6Bytes).ToString();

                OrLog(LogLevel.Verbose, "read bytes get room listen ipv6 addr:" + ipv6Addr);
                _room = new RoomInfo(roomName,
                                     response.Id,
                                     listenMode,
                                     ipv4Addr,
                                     ipv6Addr,
                                     response.StfDealPort.ToString(),
                                     response.StfSubPort.ToString(),
                                     response.StlDealPort.ToString(),
                                     response.StlSubPort.ToString(),
                                     response.Capacity,
                                     presetRoomOptions
                                     );

                subscriberListener.Start();
                dealerListener.Start();

                _room = new RoomInfo(
                    dealerListener.SetProperties,
                    dealerListener.SetPropertiesListedInLobby,
                    _room);

                OnCreatedRoomCall();
                OrLog(LogLevel.Verbose, "OnCreatedRoomCall");
                OrLog(LogLevel.Verbose, "post create room end");
            }
            private IEnumerator GetRoomList()
            {
                if (!_entryJoined || _roomJoining || _roomJoined || GetRoomListLock)
                {
                    yield break;
                }

                GetRoomListLock = true;
                OrLog(LogLevel.Verbose, "Get rooms info");
                UnityWebRequest webRequest = UnityWebRequest.Get(BASE_URL + _serverAddress + ":" + _entryPort + "/rooms");

                webRequest.SetRequestHeader("User-Agent", UA_UNITY_CDK);
                yield return(webRequest.SendWebRequest());

                if (webRequest.isNetworkError)
                {
                    OrLogError(LogLevel.Info, webRequest.error);
                    // TODO VERSION ERROR HANDLE CALLBACK
                    yield break;
                }

                var streamReader  = new MemoryStream(webRequest.downloadHandler.data);
                var messageReader = new EndiannessBinaryReader(streamReader);

                if (webRequest.responseCode != 200)
                {
                    OrLog(LogLevel.Verbose, "post create room failed. http status code:" + webRequest.responseCode);
                    OnOpenRelayCreateRoomFailedCall((short)webRequest.responseCode, " failed polling");

                    yield break;
                }

                var responseCode = (ResponseCode)messageReader.ReadUInt16();
                var roomListLen  = messageReader.ReadUInt16();

                if (responseCode == ResponseCode.OPENRELAY_RESPONSE_CODE_OK_NO_ROOM)
                {
                    OrLog(LogLevel.Verbose, "no room");
                }
                else if (responseCode == ResponseCode.OPENRELAY_RESPONSE_CODE_OK)
                {
                    List <RoomInfo> list = new List <RoomInfo>();
                    for (int index = 0; index < roomListLen; index++)
                    {
                        var responseSize  = Marshal.SizeOf(typeof(RoomResponse));
                        var responseBytes = messageReader.ReadBytes(responseSize);
                        OrLog(LogLevel.VeryVerbose, "raw response:" + BitConverter.ToString(responseBytes));
                        var          ptr = Marshal.AllocCoTaskMem(responseSize);
                        var          gch = GCHandle.Alloc(responseBytes, GCHandleType.Pinned);
                        RoomResponse response;
                        try
                        {
                            response = Marshal.PtrToStructure <RoomResponse>(gch.AddrOfPinnedObject());
                            OrLog(LogLevel.Verbose, "read bytes get room Id:" + BitConverter.ToString(response.Id));
                            OrLog(LogLevel.Verbose, "read bytes get room Capacity:" + response.Capacity.ToString());
                            OrLog(LogLevel.Verbose, "read bytes get room StfDealPort:" + response.StfDealPort.ToString());
                            OrLog(LogLevel.Verbose, "read bytes get room StfSubPort:" + response.StfSubPort.ToString());
                            OrLog(LogLevel.Verbose, "read bytes get room StlDealPort:" + response.StlDealPort.ToString());
                            OrLog(LogLevel.Verbose, "read bytes get room StlSubPort:" + response.StlSubPort.ToString());
                            OrLog(LogLevel.Verbose, "read bytes get room QueuingPolicy:" + response.QueuingPolicy.ToString());
                            OrLog(LogLevel.Verbose, "read bytes get room Flags:" + response.Flags.ToString());
                            OrLog(LogLevel.Verbose, "read bytes get room NameLen:" + response.NameLen.ToString());
                            OrLog(LogLevel.Verbose, "read bytes get room FilterLen:" + response.FilterLen.ToString());
                        }
                        catch (Exception e)
                        {
                            OrLogError(LogLevel.Info, "handle error: " + e.Message);
                            OrLogError(LogLevel.Verbose, "stacktrace: " + e.StackTrace);
                            OrLogError(LogLevel.Verbose, "post create room failed ");
                            gch.Free();

                            yield break;
                        }
                        gch.Free();

                        byte[] name = new byte[] { };
                        //if (0 < response.NameLen)
                        //{
                        name = messageReader.ReadBytes(256);
                        OrLog(LogLevel.Verbose, "read bytes get room Name:" + Encoding.UTF8.GetString(name).Substring(0, response.NameLen));
                        //}
                        byte[] filter;
                        //if (0 < response.FilterLen)
                        //{
                        filter = messageReader.ReadBytes(256);
                        OrLog(LogLevel.Verbose, "read bytes get room Filter:" + BitConverter.ToString(filter).Substring(0, response.FilterLen));
                        //}
                        var listenMode = messageReader.ReadByte();
                        OrLog(LogLevel.Verbose, "read bytes get room listen mode:" + listenMode);
                        messageReader.ReadBytes(3); // alignment 3bytes for 4byte alignment.
                        var ipv4Bytes = messageReader.ReadBytes(4);
                        var ipv4Addr  = new IPAddress(ipv4Bytes).ToString();
                        //var ipv4Addr = _serverAddress; // TODO ISSUE 24 provisional fix
                        OrLog(LogLevel.Verbose, "read bytes get room listen ipv4 addr:" + ipv4Addr);
                        var ipv6Bytes = messageReader.ReadBytes(16);
                        var ipv6Addr  = new IPAddress(ipv6Bytes).ToString();
                        OrLog(LogLevel.Verbose, "read bytes get room listen ipv6 addr:" + ipv6Addr);
                        var roomInfo = new RoomInfo(Encoding.UTF8.GetString(name).Substring(0, response.NameLen),
                                                    response.Id,
                                                    listenMode,
                                                    ipv4Addr,
                                                    ipv6Addr,
                                                    response.StfDealPort.ToString(),
                                                    response.StfSubPort.ToString(),
                                                    response.StlDealPort.ToString(),
                                                    response.StlSubPort.ToString(),
                                                    response.Capacity,
                                                    new RoomOptions());
                        roomInfo = new RoomInfo(response.UserCount, roomInfo);
                        list.Add(roomInfo);
                    }

                    foreach (var room in list)
                    {
                        yield return(StartCoroutine(GetRoomProperties(room)));

                        yield return(new WaitForSeconds(0.01f));
                    }

                    RoomList = list;
                    OnRoomListUpdateCall(RoomList);
                }

                GetRoomListLock = false;
            }