diff --git a/src/Microsoft.Net.WebSockets/CommonWebSocket.cs b/src/Microsoft.Net.WebSockets/CommonWebSocket.cs index 2f4c405c36..979ae18606 100644 --- a/src/Microsoft.Net.WebSockets/CommonWebSocket.cs +++ b/src/Microsoft.Net.WebSockets/CommonWebSocket.cs @@ -154,15 +154,8 @@ namespace Microsoft.Net.WebSockets } // Handle fragmentation, remember the first frame type - int opCode = Constants.OpCodes.ContinuationFrame; - if (_frameInProgress.OpCode == Constants.OpCodes.BinaryFrame - || _frameInProgress.OpCode == Constants.OpCodes.TextFrame - || _frameInProgress.OpCode == Constants.OpCodes.CloseFrame) - { - opCode = _frameInProgress.OpCode; - _firstDataOpCode = opCode; - } - else if (_frameInProgress.OpCode == Constants.OpCodes.ContinuationFrame) + int opCode = _frameInProgress.OpCode; + if (opCode == Constants.OpCodes.ContinuationFrame) { if (!_firstDataOpCode.HasValue) { @@ -170,39 +163,34 @@ namespace Microsoft.Net.WebSockets } opCode = _firstDataOpCode.Value; } + else + { + _firstDataOpCode = opCode; + } if (opCode == Constants.OpCodes.CloseFrame) { return await ProcessCloseFrameAsync(cancellationToken); } - WebSocketReceiveResult result; - - WebSocketMessageType messageType = Utilities.GetMessageType(opCode); - if (_frameBytesRemaining == 0) - { - // End of an empty frame? - result = new WebSocketReceiveResult(0, messageType, _frameInProgress.Fin); - if (_frameInProgress.Fin) - { - _firstDataOpCode = null; - } - _frameInProgress = null; - return result; - } - // Make sure there's at least some data in the buffer - await EnsureDataAvailableOrReadAsync(1, cancellationToken); + int bytesToBuffer = (int)Math.Min((long)_receiveBuffer.Length, _frameBytesRemaining); + await EnsureDataAvailableOrReadAsync(bytesToBuffer, cancellationToken); + // Copy buffered data to the users buffer int bytesToRead = (int)Math.Min((long)buffer.Count, _frameBytesRemaining); int bytesToCopy = Math.Min(bytesToRead, _receiveBufferBytes); Array.Copy(_receiveBuffer, _receiveBufferOffset, buffer.Array, buffer.Offset, bytesToCopy); + if (_unmaskInput) { // TODO: mask alignment may be off between reads. // _frameInProgress.Masked == _unmaskInput already verified Utilities.MaskInPlace(_frameInProgress.MaskKey, new ArraySegment(buffer.Array, buffer.Offset, bytesToCopy)); } + + WebSocketReceiveResult result; + WebSocketMessageType messageType = Utilities.GetMessageType(opCode); if (bytesToCopy == _frameBytesRemaining) { result = new WebSocketReceiveResult(bytesToCopy, messageType, _frameInProgress.Fin); @@ -216,6 +204,7 @@ namespace Microsoft.Net.WebSockets { result = new WebSocketReceiveResult(bytesToCopy, messageType, false); } + _frameBytesRemaining -= bytesToCopy; _receiveBufferBytes -= bytesToCopy; _receiveBufferOffset += bytesToCopy; @@ -370,7 +359,7 @@ namespace Microsoft.Net.WebSockets if (State == WebSocketState.CloseSent) { // Do a receiving drain - byte[] data = new byte[1024]; + byte[] data = new byte[_receiveBuffer.Length]; WebSocketReceiveResult result; do { diff --git a/src/Microsoft.Net.WebSockets/Utilities.cs b/src/Microsoft.Net.WebSockets/Utilities.cs index 35be77a857..a4fdcfda4b 100644 --- a/src/Microsoft.Net.WebSockets/Utilities.cs +++ b/src/Microsoft.Net.WebSockets/Utilities.cs @@ -33,10 +33,11 @@ namespace Microsoft.Net.WebSockets }; int maskOffset = 0; - for (int i = data.Offset; i < data.Offset + data.Count; i++) + int end = data.Offset + data.Count; + for (int i = data.Offset; i < end; i++) { - data.Array[i] = (byte)(data.Array[i] ^ maskBytes[maskOffset]); - maskOffset = (maskOffset + 1) % 4; + data.Array[i] ^= maskBytes[maskOffset]; + maskOffset = (maskOffset + 1) & 0x3; // fast % 4; } } diff --git a/src/Microsoft.Net.WebSockets/WebSocketClient.cs b/src/Microsoft.Net.WebSockets/WebSocketClient.cs index d1ec49b4d5..a5c5c666a4 100644 --- a/src/Microsoft.Net.WebSockets/WebSocketClient.cs +++ b/src/Microsoft.Net.WebSockets/WebSocketClient.cs @@ -24,7 +24,7 @@ namespace Microsoft.Net.WebSockets.Client public WebSocketClient() { - ReceiveBufferSize = 1024; + ReceiveBufferSize = 1024 * 64; } public int ReceiveBufferSize diff --git a/test/TestClient/Program.cs b/test/TestClient/Program.cs index 2c16bc5576..ac36c45d96 100644 --- a/test/TestClient/Program.cs +++ b/test/TestClient/Program.cs @@ -22,13 +22,23 @@ namespace TestClient { WebSocketClient client = new WebSocketClient(); WebSocket socket = await client.ConnectAsync(new Uri("ws://chrross-togo:12345/"), CancellationToken.None); - byte[] data = Encoding.UTF8.GetBytes("Hello World"); + byte[] data = Encoding.UTF8.GetBytes( + // TODO: Hangs after 10 seconds + // "Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World" + // "Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, " + // "Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, " + "Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, Hello World, " + ); while (true) { await socket.SendAsync(new ArraySegment(data), WebSocketMessageType.Text, true, CancellationToken.None); - WebSocketReceiveResult result = await socket.ReceiveAsync(new ArraySegment(data), CancellationToken.None); - Console.WriteLine(result.MessageType + ", " + result.Count + ", " + result.EndOfMessage); - Console.WriteLine(Encoding.UTF8.GetString(data, 0, result.Count)); + WebSocketReceiveResult result; + do + { + result = await socket.ReceiveAsync(new ArraySegment(data), CancellationToken.None); + // Console.WriteLine("Received: " + result.MessageType + ", " + result.Count + ", " + result.EndOfMessage); + } while (!result.EndOfMessage); + // Console.WriteLine(Encoding.UTF8.GetString(data, 0, result.Count)); } await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None); } diff --git a/test/TestServer/Program.cs b/test/TestServer/Program.cs index 59b5825b55..c3c9384aab 100644 --- a/test/TestServer/Program.cs +++ b/test/TestServer/Program.cs @@ -41,7 +41,7 @@ namespace TestServer while (received.MessageType != WebSocketMessageType.Close) { - Console.WriteLine("Echo"); + // Console.WriteLine("Echo, " + received.Count + ", " + received.MessageType + ", " + received.EndOfMessage); // Echo anything we receive await webSocket.SendAsync(new ArraySegment(buffer, 0, received.Count), received.MessageType, received.EndOfMessage, CancellationToken.None);