Beispiel #1
0
        private async Task SendFrameFallbackAsync(MazeSocket.MessageOpcode opcode, ArraySegment <byte> payloadBuffer, bool bufferHasRequiredLength,
                                                  CancellationToken cancellationToken)
        {
            var sendBuffer = WriteFrameToSendBuffer(opcode, payloadBuffer, bufferHasRequiredLength);

            try
            {
                await _sendFrameAsyncLock.WaitAsync(cancellationToken).ConfigureAwait(false);

                try
                {
                    await WebSocket.SendAsync(sendBuffer, WebSocketMessageType.Binary, true, cancellationToken);
                }
                finally
                {
                    _sendFrameAsyncLock.Release();
                }
            }
            finally
            {
                if (!bufferHasRequiredLength)
                {
                    ReleaseSendBuffer(sendBuffer.Array);
                }
            }
        }
Beispiel #2
0
        private Task SendFrameLockAcquiredNonCancelableAsync(MazeSocket.MessageOpcode opcode, ArraySegment <byte> payloadBuffer, bool bufferHasRequiredLength, CancellationToken cancellationToken)
        {
            // If we get here, the cancellation token is not cancelable so we don't have to worry about it,
            // and we own the semaphore, so we don't need to asynchronously wait for it.
            Task writeTask;
            var  releaseSemaphoreAndSendBuffer = true;
            var  sendBuffer = WriteFrameToSendBuffer(opcode, payloadBuffer, bufferHasRequiredLength);

            try
            {
                // Write the payload synchronously to the buffer, then write that buffer out to the network.
                writeTask = WebSocket.SendAsync(sendBuffer, WebSocketMessageType.Binary, true, cancellationToken);

                // If the operation happens to complete synchronously (or, more specifically, by
                // the time we get from the previous line to here), release the semaphore, return
                // the task, and we're done.
                if (writeTask.IsCompleted)
                {
                    return(writeTask);
                }

                // Up until this point, if an exception occurred (such as when accessing _stream or when
                // calling GetResult), we want to release the semaphore and the send buffer. After this point,
                // both need to be held until writeTask completes.
                releaseSemaphoreAndSendBuffer = false;
            }
            finally
            {
                if (releaseSemaphoreAndSendBuffer)
                {
                    _sendFrameAsyncLock.Release();

                    if (!bufferHasRequiredLength)
                    {
                        ReleaseSendBuffer(sendBuffer.Array);
                    }
                }
            }

            return(writeTask.ContinueWith((t, s) =>
            {
                var thisRef = (WebSocketWrapper)s;
                thisRef._sendFrameAsyncLock.Release();

                if (!bufferHasRequiredLength)
                {
                    thisRef.ReleaseSendBuffer(sendBuffer.Array);
                }
            }, this, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default));
        }
Beispiel #3
0
        /// <summary>Writes a frame into the send buffer, which can then be sent over the network.</summary>
        private ArraySegment <byte> WriteFrameToSendBuffer(MazeSocket.MessageOpcode opcode, ArraySegment <byte> payloadBuffer, bool bufferHasRequiredLength)
        {
            if (bufferHasRequiredLength)
            {
                payloadBuffer.Array[payloadBuffer.Offset - 1] = (byte)opcode;
                return(new ArraySegment <byte>(payloadBuffer.Array, payloadBuffer.Offset - 1, payloadBuffer.Count + 1));
            }

            var sendBuffer = AllocateSendBuffer(payloadBuffer.Count + 1);

            sendBuffer[0] = (byte)opcode;

            if (payloadBuffer.Count > 0)
            {
                Buffer.BlockCopy(payloadBuffer.Array, payloadBuffer.Offset, sendBuffer, 1,
                                 payloadBuffer.Count);
            }

            return(new ArraySegment <byte>(sendBuffer, 0, 1 + payloadBuffer.Count));
        }
Beispiel #4
0
 public DataReceivedEventArgs(BufferSegment buffer, MazeSocket.MessageOpcode opcode)
 {
     Buffer = buffer;
     Opcode = opcode;
 }
Beispiel #5
0
 public Task SendFrameAsync(MazeSocket.MessageOpcode opcode, ArraySegment <byte> payloadBuffer,
                            bool bufferHasRequiredLength, CancellationToken cancellationToken) =>
 !_sendFrameAsyncLock.Wait(0)
         ? SendFrameFallbackAsync(opcode, payloadBuffer, bufferHasRequiredLength, cancellationToken)
         : SendFrameLockAcquiredNonCancelableAsync(opcode, payloadBuffer, bufferHasRequiredLength, cancellationToken);