diff --git a/build/common.props b/build/common.props
index c7f5bae299..4954e5032a 100644
--- a/build/common.props
+++ b/build/common.props
@@ -16,8 +16,8 @@
-
-
+
+
diff --git a/build/dependencies.props b/build/dependencies.props
index c07fc9e447..67ec9bf6fa 100644
--- a/build/dependencies.props
+++ b/build/dependencies.props
@@ -3,8 +3,9 @@
2.0.0-*
0.4.0-*
1.0.0-*
+ 4.4.0-*
2.1.0-*
- $(BundledNETStandardPackageVersion)
+ 2.0.0-*
15.3.0-*
2.3.0-beta2-*
diff --git a/samples/EchoApp/EchoApp.csproj b/samples/EchoApp/EchoApp.csproj
index 0aac572423..6499a0a23f 100644
--- a/samples/EchoApp/EchoApp.csproj
+++ b/samples/EchoApp/EchoApp.csproj
@@ -3,7 +3,7 @@
- netcoreapp2.0
+ netcoreapp2.0;net461
@@ -18,4 +18,8 @@
+
+
+
+
diff --git a/src/Microsoft.AspNetCore.WebSockets/Microsoft.AspNetCore.WebSockets.csproj b/src/Microsoft.AspNetCore.WebSockets/Microsoft.AspNetCore.WebSockets.csproj
index fd8de4d0df..2f2730ab86 100644
--- a/src/Microsoft.AspNetCore.WebSockets/Microsoft.AspNetCore.WebSockets.csproj
+++ b/src/Microsoft.AspNetCore.WebSockets/Microsoft.AspNetCore.WebSockets.csproj
@@ -4,7 +4,7 @@
ASP.NET Core web socket middleware for use on top of opaque servers.
- netcoreapp2.0
+ netstandard2.0
$(NoWarn);CS1591
true
true
@@ -14,6 +14,7 @@
+
diff --git a/test/Microsoft.AspNetCore.WebSockets.Test/BufferStream.cs b/test/Microsoft.AspNetCore.WebSockets.Test/BufferStream.cs
index bba60a658b..1916bf8f4b 100644
--- a/test/Microsoft.AspNetCore.WebSockets.Test/BufferStream.cs
+++ b/test/Microsoft.AspNetCore.WebSockets.Test/BufferStream.cs
@@ -152,6 +152,71 @@ namespace Microsoft.AspNetCore.WebSockets.Test
}
}
+ public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
+ {
+ // TODO: This option doesn't preserve the state object.
+ // return ReadAsync(buffer, offset, count);
+ return base.BeginRead(buffer, offset, count, callback, state);
+ }
+
+ public override int EndRead(IAsyncResult asyncResult)
+ {
+ // return ((Task)asyncResult).Result;
+ return base.EndRead(asyncResult);
+ }
+
+ public async override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
+ {
+ if (_terminated)
+ {
+ return 0;
+ }
+
+ VerifyBuffer(buffer, offset, count, allowEmpty: false);
+ var registration = cancellationToken.Register(Abort);
+ await _readLock.WaitAsync(cancellationToken);
+ try
+ {
+ int totalRead = 0;
+ do
+ {
+ // Don't drained buffered data on abort.
+ CheckAborted();
+ if (_topBuffer.Count <= 0)
+ {
+ byte[] topBuffer = null;
+ while (!_bufferedData.TryDequeue(out topBuffer))
+ {
+ if (_disposed)
+ {
+ CheckAborted();
+ // Graceful close
+ return totalRead;
+ }
+ await WaitForDataAsync();
+ }
+ _topBuffer = new ArraySegment(topBuffer);
+ }
+ var actualCount = Math.Min(count, _topBuffer.Count);
+ Buffer.BlockCopy(_topBuffer.Array, _topBuffer.Offset, buffer, offset, actualCount);
+ _topBuffer = new ArraySegment(_topBuffer.Array,
+ _topBuffer.Offset + actualCount,
+ _topBuffer.Count - actualCount);
+ totalRead += actualCount;
+ offset += actualCount;
+ count -= actualCount;
+ }
+ while (count > 0 && (_topBuffer.Count > 0 || _bufferedData.Count > 0));
+ // Keep reading while there is more data available and we have more space to put it in.
+ return totalRead;
+ }
+ finally
+ {
+ registration.Dispose();
+ _readLock.Release();
+ }
+ }
+
// Write with count 0 will still trigger OnFirstWrite
public override void Write(byte[] buffer, int offset, int count)
{
@@ -166,7 +231,7 @@ namespace Microsoft.AspNetCore.WebSockets.Test
return;
}
// Copies are necessary because we don't know what the caller is going to do with the buffer afterwards.
- byte[] internalBuffer = new byte[count];
+ var internalBuffer = new byte[count];
Buffer.BlockCopy(buffer, offset, internalBuffer, 0, count);
_bufferedData.Enqueue(internalBuffer);
@@ -178,6 +243,35 @@ namespace Microsoft.AspNetCore.WebSockets.Test
}
}
+ public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
+ {
+ Write(buffer, offset, count);
+ var tcs = new TaskCompletionSource