/// <summary> /// reads a message from connection /// </summary> /// <param name="buffer">buffer where the message will be written</param> /// <returns>true if we got a message, false if we got disconnected</returns> public async UniTask <int> ReceiveAsync(MemoryStream buffer) { while (kcp.PeekSize() < 0 && unreliable.PeekSize() < 0 && open) { isWaiting = true; dataAvailable = AutoResetUniTaskCompletionSource.Create(); await dataAvailable.Task; isWaiting = false; } if (!open) { Disconnected?.Invoke(); throw new EndOfStreamException(); } if (unreliable.PeekSize() >= 0) { // we got a message in the unreliable channel int msgSize = unreliable.PeekSize(); buffer.SetLength(msgSize); unreliable.Receive(buffer.GetBuffer(), (int)buffer.Length); buffer.Position = msgSize; return(Channel.Unreliable); } else { int msgSize = kcp.PeekSize(); // we have some data, return it buffer.SetLength(msgSize); kcp.Receive(buffer.GetBuffer()); buffer.Position = msgSize; // if we receive a disconnect message, then close everything var dataSegment = new ArraySegment <byte>(buffer.GetBuffer(), 0, msgSize); if (Utils.Equal(dataSegment, Goodby)) { open = false; Disconnected?.Invoke(); throw new EndOfStreamException(); } return(Channel.Reliable); } }