/// <summary> /// Process receive frame. /// </summary> /// <param name="frame">The current frame.</param> private void ReceiveFrame(Frame frame) { // Process the frame that was received. if (ProcessReceivedFrame(frame) && _readyState != WebSocketConnectionState.Closed) { // If is not data frame. if (!frame.IsData) { return; } // Lock until complete. lock (_lockReceive) { try { // Is data frame. MessageEventArgs messsage = DequeueFromMessageEventQueue(); if (messsage != null && _readyState == WebSocketConnectionState.Open) { // Get all the frame data. byte[] data = messsage.RawData; MessageType opcode = OpCodeTypeHelper.GetMessageType(messsage.Type); bool endOfMessage = frame.IsFinal; int count = (data != null ? data.Length : 0); // Create the result; ReceiveResult result = new ReceiveResult(count, opcode, endOfMessage); _receiveResult.Data = data; _receiveResult.Offset = 0; _receiveResult.Result = result; _receiveResult.ReturnComplete = false; // Enqueue the result. _recevedFrame.Set(); } } catch (Exception ex) { ProcessException(ex, "An exception has occurred during an OnMessage event."); } } } else { // Unable to process the frame close the connection. _exitReceiving.Set(); } }
/// <summary> /// Receives data from the WebSocket connection asynchronously. /// </summary> /// <param name="buffer">References the application buffer that is the storage location for the received data.</param> /// <param name="cancellationToken">Propagate the notification that operations should be canceled.</param> /// <returns>Returns System.Threading.Tasks.Task.</returns> public Task <ReceiveResult> ReceiveAsync(ArraySegment <byte> buffer, CancellationToken cancellationToken) { // Create a new task. return(Task <ReceiveResult> .Factory.StartNew(() => { bool notWait = false; ReceiveResult result = null; // Lock until complete. lock (_lockReceive) { // Should the process wait. notWait = _receiveResult.ReturnComplete; } // If more data needs to be returned // then wait until complete. if (!notWait) { _recevedFrame.WaitOne(); } // Lock until complete. lock (_lockReceive) { try { // Denqueue the result. result = _receiveResult.Result; byte[] data = _receiveResult.Data; int dataOffet = _receiveResult.Offset; // Result exists. if (result != null) { // If data exists. if (data != null && buffer != null) { // Get the current offset positions // to start reading from. int left = data.Length - dataOffet; int arraySize = buffer.Array.Length; int end = arraySize >= left ? left : arraySize; // Assign the current set of data // into the buffer array. for (int i = 0; i < end; i++) { buffer.Array[i] = data[i + dataOffet]; } // Set the data offset position. _receiveResult.Offset = dataOffet + end; // If no more to send to the caller. if (_receiveResult.Offset >= data.Length) { // Let the async mode continue. _receiveResult.ReturnComplete = false; _frameReturnedComplete.Set(); } else { // Run this method again to get the next set of data. _receiveResult.ReturnComplete = true; } } } } catch { // Let the async mode continue. _receiveResult.ReturnComplete = false; _frameReturnedComplete.Set(); } } // Return the result. return result; }, cancellationToken)); }