Add GetMessageBytes to IHubProtocol (#1915)
This commit is contained in:
parent
31dfe91962
commit
8a3516284e
|
|
@ -69,6 +69,11 @@ namespace Microsoft.AspNetCore.SignalR.Microbenchmarks
|
||||||
public void WriteMessage(HubMessage message, IBufferWriter<byte> output)
|
public void WriteMessage(HubMessage message, IBufferWriter<byte> output)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte[] GetMessageBytes(HubMessage message)
|
||||||
|
{
|
||||||
|
return HubProtocolExtensions.GetMessageBytes(this, message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NoErrorHubConnectionContext : HubConnectionContext
|
public class NoErrorHubConnectionContext : HubConnectionContext
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.SignalR.Microbenchmarks
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_binaryInput = _hubProtocol.WriteToArray(_hubMessage);
|
_binaryInput = _hubProtocol.GetMessageBytes(_hubMessage);
|
||||||
_binder = new TestBinder(_hubMessage);
|
_binder = new TestBinder(_hubMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -67,7 +67,7 @@ namespace Microsoft.AspNetCore.SignalR.Microbenchmarks
|
||||||
[Benchmark]
|
[Benchmark]
|
||||||
public void WriteSingleMessage()
|
public void WriteSingleMessage()
|
||||||
{
|
{
|
||||||
var bytes = _hubProtocol.WriteToArray(_hubMessage);
|
var bytes = _hubProtocol.GetMessageBytes(_hubMessage);
|
||||||
if (bytes.Length != _binaryInput.Length)
|
if (bytes.Length != _binaryInput.Length)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("Failed to write message");
|
throw new InvalidOperationException("Failed to write message");
|
||||||
|
|
|
||||||
|
|
@ -194,6 +194,11 @@ namespace Microsoft.AspNetCore.SignalR.Microbenchmarks
|
||||||
_innerProtocol.WriteMessage(message, output);
|
_innerProtocol.WriteMessage(message, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte[] GetMessageBytes(HubMessage message)
|
||||||
|
{
|
||||||
|
return HubProtocolExtensions.GetMessageBytes(this, message);
|
||||||
|
}
|
||||||
|
|
||||||
public bool IsVersionSupported(int version)
|
public bool IsVersionSupported(int version)
|
||||||
{
|
{
|
||||||
return _innerProtocol.IsVersionSupported(version);
|
return _innerProtocol.IsVersionSupported(version);
|
||||||
|
|
|
||||||
|
|
@ -143,6 +143,11 @@ namespace Microsoft.AspNetCore.SignalR.Microbenchmarks
|
||||||
{
|
{
|
||||||
output.Write(_fixedOutput);
|
output.Write(_fixedOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte[] GetMessageBytes(HubMessage message)
|
||||||
|
{
|
||||||
|
return HubProtocolExtensions.GetMessageBytes(this, message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ namespace Microsoft.AspNetCore.SignalR.Microbenchmarks
|
||||||
}
|
}
|
||||||
|
|
||||||
_parser = new ServerSentEventsMessageParser();
|
_parser = new ServerSentEventsMessageParser();
|
||||||
_rawData = hubProtocol.WriteToArray(hubMessage);
|
_rawData = hubProtocol.GetMessageBytes(hubMessage);
|
||||||
var ms = new MemoryStream();
|
var ms = new MemoryStream();
|
||||||
ServerSentEventsMessageFormatter.WriteMessage(_rawData, ms);
|
ServerSentEventsMessageFormatter.WriteMessage(_rawData, ms);
|
||||||
_sseFormattedData = ms.ToArray();
|
_sseFormattedData = ms.ToArray();
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
using System.Buffers;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
@ -217,6 +218,35 @@ namespace Microsoft.AspNetCore.Internal
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void CopyTo(Span<byte> span)
|
||||||
|
{
|
||||||
|
Debug.Assert(span.Length >= _bytesWritten);
|
||||||
|
|
||||||
|
if (_currentSegment == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var totalWritten = 0;
|
||||||
|
|
||||||
|
if (_fullSegments != null)
|
||||||
|
{
|
||||||
|
// Copy full segments
|
||||||
|
var count = _fullSegments.Count;
|
||||||
|
for (var i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
var segment = _fullSegments[i];
|
||||||
|
segment.AsSpan().CopyTo(span.Slice(totalWritten));
|
||||||
|
totalWritten += segment.Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy current incomplete segment
|
||||||
|
_currentSegment.AsSpan(0, _position).CopyTo(span.Slice(totalWritten));
|
||||||
|
|
||||||
|
Debug.Assert(_bytesWritten == totalWritten + _position);
|
||||||
|
}
|
||||||
|
|
||||||
public override void Flush() { }
|
public override void Flush() { }
|
||||||
public override Task FlushAsync(CancellationToken cancellationToken) => Task.CompletedTask;
|
public override Task FlushAsync(CancellationToken cancellationToken) => Task.CompletedTask;
|
||||||
public override int Read(byte[] buffer, int offset, int count) => throw new NotSupportedException();
|
public override int Read(byte[] buffer, int offset, int count) => throw new NotSupportedException();
|
||||||
|
|
|
||||||
|
|
@ -10,15 +10,21 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Formatters
|
||||||
{
|
{
|
||||||
public static void WriteLengthPrefix(long length, IBufferWriter<byte> output)
|
public static void WriteLengthPrefix(long length, IBufferWriter<byte> output)
|
||||||
{
|
{
|
||||||
// This code writes length prefix of the message as a VarInt. Read the comment in
|
|
||||||
// the BinaryMessageParser.TryParseMessage for details.
|
|
||||||
|
|
||||||
Span<byte> lenBuffer = stackalloc byte[5];
|
Span<byte> lenBuffer = stackalloc byte[5];
|
||||||
|
|
||||||
|
var lenNumBytes = WriteLengthPrefix(length, lenBuffer);
|
||||||
|
|
||||||
|
output.Write(lenBuffer.Slice(0, lenNumBytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int WriteLengthPrefix(long length, Span<byte> output)
|
||||||
|
{
|
||||||
|
// This code writes length prefix of the message as a VarInt. Read the comment in
|
||||||
|
// the BinaryMessageParser.TryParseMessage for details.
|
||||||
var lenNumBytes = 0;
|
var lenNumBytes = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ref var current = ref lenBuffer[lenNumBytes];
|
ref var current = ref output[lenNumBytes];
|
||||||
current = (byte)(length & 0x7f);
|
current = (byte)(length & 0x7f);
|
||||||
length >>= 7;
|
length >>= 7;
|
||||||
if (length > 0)
|
if (length > 0)
|
||||||
|
|
@ -29,7 +35,20 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Formatters
|
||||||
}
|
}
|
||||||
while (length > 0);
|
while (length > 0);
|
||||||
|
|
||||||
output.Write(lenBuffer.Slice(0, lenNumBytes));
|
return lenNumBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int LengthPrefixLength(long length)
|
||||||
|
{
|
||||||
|
var lenNumBytes = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
length >>= 7;
|
||||||
|
lenNumBytes++;
|
||||||
|
}
|
||||||
|
while (length > 0);
|
||||||
|
|
||||||
|
return lenNumBytes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Protocol
|
||||||
{
|
{
|
||||||
public static class HubProtocolExtensions
|
public static class HubProtocolExtensions
|
||||||
{
|
{
|
||||||
public static byte[] WriteToArray(this IHubProtocol hubProtocol, HubMessage message)
|
// Would work as default interface impl
|
||||||
|
public static byte[] GetMessageBytes(this IHubProtocol hubProtocol, HubMessage message)
|
||||||
{
|
{
|
||||||
var writer = MemoryBufferWriter.Get();
|
var writer = MemoryBufferWriter.Get();
|
||||||
try
|
try
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System.Buffers;
|
using System.Buffers;
|
||||||
using System.IO;
|
|
||||||
using Microsoft.AspNetCore.Connections;
|
using Microsoft.AspNetCore.Connections;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.SignalR.Internal.Protocol
|
namespace Microsoft.AspNetCore.SignalR.Internal.Protocol
|
||||||
|
|
@ -19,6 +18,8 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Protocol
|
||||||
|
|
||||||
void WriteMessage(HubMessage message, IBufferWriter<byte> output);
|
void WriteMessage(HubMessage message, IBufferWriter<byte> output);
|
||||||
|
|
||||||
|
byte[] GetMessageBytes(HubMessage message);
|
||||||
|
|
||||||
bool IsVersionSupported(int version);
|
bool IsVersionSupported(int version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -340,7 +340,7 @@ namespace Microsoft.AspNetCore.SignalR
|
||||||
transferFormatFeature.ActiveFormat = Protocol.TransferFormat;
|
transferFormatFeature.ActiveFormat = Protocol.TransferFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
_cachedPingMessage = Protocol.WriteToArray(PingMessage.Instance);
|
_cachedPingMessage = Protocol.GetMessageBytes(PingMessage.Instance);
|
||||||
|
|
||||||
UserIdentifier = userIdProvider.GetUserId(this);
|
UserIdentifier = userIdProvider.GetUserId(this);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
|
||||||
"This message was received from another server that did not have the requested protocol available.");
|
"This message was received from another server that did not have the requested protocol available.");
|
||||||
}
|
}
|
||||||
|
|
||||||
serialized = protocol.WriteToArray(Message);
|
serialized = protocol.GetMessageBytes(Message);
|
||||||
SetCache(protocol.Name, serialized);
|
SetCache(protocol.Name, serialized);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -65,7 +65,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal
|
||||||
{
|
{
|
||||||
writer.Write(protocol.Name);
|
writer.Write(protocol.Name);
|
||||||
|
|
||||||
var buffer = protocol.WriteToArray(message);
|
var buffer = protocol.GetMessageBytes(message);
|
||||||
writer.Write(buffer.Length);
|
writer.Write(buffer.Length);
|
||||||
writer.Write(buffer);
|
writer.Write(buffer);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,11 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Protocol
|
||||||
TextMessageFormatter.WriteRecordSeparator(output);
|
TextMessageFormatter.WriteRecordSeparator(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte[] GetMessageBytes(HubMessage message)
|
||||||
|
{
|
||||||
|
return HubProtocolExtensions.GetMessageBytes(this, message);
|
||||||
|
}
|
||||||
|
|
||||||
private HubMessage ParseMessage(Utf8BufferTextReader textReader, IInvocationBinder binder)
|
private HubMessage ParseMessage(Utf8BufferTextReader textReader, IInvocationBinder binder)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
||||||
|
|
@ -303,6 +303,34 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Protocol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte[] GetMessageBytes(HubMessage message)
|
||||||
|
{
|
||||||
|
var writer = MemoryBufferWriter.Get();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Write message to a buffer so we can get its length
|
||||||
|
WriteMessageCore(message, writer);
|
||||||
|
|
||||||
|
var dataLength = writer.Length;
|
||||||
|
var prefixLength = BinaryMessageFormatter.LengthPrefixLength(writer.Length);
|
||||||
|
|
||||||
|
var array = new byte[dataLength + prefixLength];
|
||||||
|
var span = array.AsSpan();
|
||||||
|
|
||||||
|
// Write length then message to output
|
||||||
|
var written = BinaryMessageFormatter.WriteLengthPrefix(writer.Length, span);
|
||||||
|
Debug.Assert(written == prefixLength);
|
||||||
|
writer.CopyTo(span.Slice(prefixLength));
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
MemoryBufferWriter.Return(writer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void WriteMessageCore(HubMessage message, Stream packer)
|
private void WriteMessageCore(HubMessage message, Stream packer)
|
||||||
{
|
{
|
||||||
switch (message)
|
switch (message)
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,11 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests
|
||||||
throw _error;
|
throw _error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte[] GetMessageBytes(HubMessage message)
|
||||||
|
{
|
||||||
|
return HubProtocolExtensions.GetMessageBytes(this, message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,18 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void WritingNotingGivesEmptyData_CopyTo()
|
||||||
|
{
|
||||||
|
using (var bufferWriter = new MemoryBufferWriter())
|
||||||
|
{
|
||||||
|
Assert.Equal(0, bufferWriter.Length);
|
||||||
|
var data = new byte[bufferWriter.Length];
|
||||||
|
bufferWriter.CopyTo(data);
|
||||||
|
Assert.Empty(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void WriteByteWorksAsFirstCall()
|
public void WriteByteWorksAsFirstCall()
|
||||||
{
|
{
|
||||||
|
|
@ -48,6 +60,21 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void WriteByteWorksAsFirstCall_CopyTo()
|
||||||
|
{
|
||||||
|
using (var bufferWriter = new MemoryBufferWriter())
|
||||||
|
{
|
||||||
|
bufferWriter.WriteByte(234);
|
||||||
|
|
||||||
|
Assert.Equal(1, bufferWriter.Length);
|
||||||
|
var data = new byte[bufferWriter.Length];
|
||||||
|
|
||||||
|
bufferWriter.CopyTo(data);
|
||||||
|
Assert.Equal(234, data[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void WriteByteWorksIfFirstByteInNewSegment()
|
public void WriteByteWorksIfFirstByteInNewSegment()
|
||||||
{
|
{
|
||||||
|
|
@ -67,6 +94,27 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void WriteByteWorksIfFirstByteInNewSegment_CopyTo()
|
||||||
|
{
|
||||||
|
var inputSize = MinimumSegmentSize;
|
||||||
|
var input = Enumerable.Range(0, inputSize).Select(i => (byte)i).ToArray();
|
||||||
|
|
||||||
|
using (var bufferWriter = new MemoryBufferWriter(MinimumSegmentSize))
|
||||||
|
{
|
||||||
|
bufferWriter.Write(input, 0, input.Length);
|
||||||
|
Assert.Equal(16, bufferWriter.Length);
|
||||||
|
bufferWriter.WriteByte(16);
|
||||||
|
Assert.Equal(17, bufferWriter.Length);
|
||||||
|
|
||||||
|
var data = new byte[bufferWriter.Length];
|
||||||
|
|
||||||
|
bufferWriter.CopyTo(data);
|
||||||
|
Assert.Equal(input, data.Take(16));
|
||||||
|
Assert.Equal(16, data[16]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void WriteByteWorksIfSegmentHasSpace()
|
public void WriteByteWorksIfSegmentHasSpace()
|
||||||
{
|
{
|
||||||
|
|
@ -88,6 +136,28 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void WriteByteWorksIfSegmentHasSpace_CopyTo()
|
||||||
|
{
|
||||||
|
var input = new byte[] { 11, 12, 13 };
|
||||||
|
|
||||||
|
using (var bufferWriter = new MemoryBufferWriter())
|
||||||
|
{
|
||||||
|
bufferWriter.Write(input, 0, input.Length);
|
||||||
|
bufferWriter.WriteByte(14);
|
||||||
|
|
||||||
|
Assert.Equal(4, bufferWriter.Length);
|
||||||
|
|
||||||
|
var data = new byte[bufferWriter.Length];
|
||||||
|
|
||||||
|
bufferWriter.CopyTo(data);
|
||||||
|
Assert.Equal(11, data[0]);
|
||||||
|
Assert.Equal(12, data[1]);
|
||||||
|
Assert.Equal(13, data[2]);
|
||||||
|
Assert.Equal(14, data[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ToArrayWithExactlyFullSegmentsWorks()
|
public void ToArrayWithExactlyFullSegmentsWorks()
|
||||||
{
|
{
|
||||||
|
|
@ -104,6 +174,24 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ToArrayWithExactlyFullSegmentsWorks_CopyTo()
|
||||||
|
{
|
||||||
|
var inputSize = MinimumSegmentSize * 2;
|
||||||
|
var input = Enumerable.Range(0, inputSize).Select(i => (byte)i).ToArray();
|
||||||
|
|
||||||
|
using (var bufferWriter = new MemoryBufferWriter(MinimumSegmentSize))
|
||||||
|
{
|
||||||
|
bufferWriter.Write(input, 0, input.Length);
|
||||||
|
Assert.Equal(input.Length, bufferWriter.Length);
|
||||||
|
|
||||||
|
var data = new byte[bufferWriter.Length];
|
||||||
|
|
||||||
|
bufferWriter.CopyTo(data);
|
||||||
|
Assert.Equal(input, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ToArrayWithSomeFullSegmentsWorks()
|
public void ToArrayWithSomeFullSegmentsWorks()
|
||||||
{
|
{
|
||||||
|
|
@ -120,6 +208,23 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ToArrayWithSomeFullSegmentsWorks_CopyTo()
|
||||||
|
{
|
||||||
|
var inputSize = (MinimumSegmentSize * 2) + 1;
|
||||||
|
var input = Enumerable.Range(0, inputSize).Select(i => (byte)i).ToArray();
|
||||||
|
|
||||||
|
using (var bufferWriter = new MemoryBufferWriter(MinimumSegmentSize))
|
||||||
|
{
|
||||||
|
bufferWriter.Write(input, 0, input.Length);
|
||||||
|
Assert.Equal(input.Length, bufferWriter.Length);
|
||||||
|
var data = new byte[bufferWriter.Length];
|
||||||
|
|
||||||
|
bufferWriter.CopyTo(data);
|
||||||
|
Assert.Equal(input, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task CopyToAsyncWithExactlyFullSegmentsWorks()
|
public async Task CopyToAsyncWithExactlyFullSegmentsWorks()
|
||||||
{
|
{
|
||||||
|
|
@ -177,6 +282,34 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CopyToWithExactlyFullSegmentsWorks_CopyTo()
|
||||||
|
{
|
||||||
|
var inputSize = MinimumSegmentSize * 2;
|
||||||
|
var input = Enumerable.Range(0, inputSize).Select(i => (byte)i).ToArray();
|
||||||
|
|
||||||
|
using (var bufferWriter = new MemoryBufferWriter(MinimumSegmentSize))
|
||||||
|
{
|
||||||
|
bufferWriter.Write(input, 0, input.Length);
|
||||||
|
Assert.Equal(input.Length, bufferWriter.Length);
|
||||||
|
|
||||||
|
using (var destination = new MemoryBufferWriter())
|
||||||
|
{
|
||||||
|
bufferWriter.CopyTo(destination);
|
||||||
|
var data = new byte[bufferWriter.Length];
|
||||||
|
|
||||||
|
bufferWriter.CopyTo(data);
|
||||||
|
Assert.Equal(input, data);
|
||||||
|
|
||||||
|
Array.Clear(data, 0, data.Length);
|
||||||
|
|
||||||
|
destination.CopyTo(data);
|
||||||
|
Assert.Equal(input, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void CopyToWithSomeFullSegmentsWorks()
|
public void CopyToWithSomeFullSegmentsWorks()
|
||||||
{
|
{
|
||||||
|
|
@ -197,6 +330,34 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CopyToWithSomeFullSegmentsWorks_CopyTo()
|
||||||
|
{
|
||||||
|
var inputSize = (MinimumSegmentSize * 2) + 1;
|
||||||
|
var input = Enumerable.Range(0, inputSize).Select(i => (byte)i).ToArray();
|
||||||
|
|
||||||
|
using (var bufferWriter = new MemoryBufferWriter(MinimumSegmentSize))
|
||||||
|
{
|
||||||
|
bufferWriter.Write(input, 0, input.Length);
|
||||||
|
Assert.Equal(input.Length, bufferWriter.Length);
|
||||||
|
|
||||||
|
using (var destination = new MemoryBufferWriter())
|
||||||
|
{
|
||||||
|
bufferWriter.CopyTo(destination);
|
||||||
|
var data = new byte[bufferWriter.Length];
|
||||||
|
bufferWriter.CopyTo(data);
|
||||||
|
|
||||||
|
Assert.Equal(input, data);
|
||||||
|
|
||||||
|
Array.Clear(data, 0, data.Length);
|
||||||
|
|
||||||
|
destination.CopyTo(data);
|
||||||
|
Assert.Equal(input, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if NETCOREAPP2_1
|
#if NETCOREAPP2_1
|
||||||
[Fact]
|
[Fact]
|
||||||
public void WriteSpanWorksAtNonZeroOffset()
|
public void WriteSpanWorksAtNonZeroOffset()
|
||||||
|
|
@ -216,6 +377,25 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol
|
||||||
Assert.Equal(4, data[3]);
|
Assert.Equal(4, data[3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void WriteSpanWorksAtNonZeroOffset_CopyTo()
|
||||||
|
{
|
||||||
|
using (var bufferWriter = new MemoryBufferWriter())
|
||||||
|
{
|
||||||
|
bufferWriter.WriteByte(1);
|
||||||
|
bufferWriter.Write(new byte[] { 2, 3, 4 }.AsSpan());
|
||||||
|
|
||||||
|
Assert.Equal(4, bufferWriter.Length);
|
||||||
|
|
||||||
|
var data = new byte[bufferWriter.Length];
|
||||||
|
bufferWriter.CopyTo(data);
|
||||||
|
Assert.Equal(1, data[0]);
|
||||||
|
Assert.Equal(2, data[1]);
|
||||||
|
Assert.Equal(3, data[2]);
|
||||||
|
Assert.Equal(4, data[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
|
|
||||||
public async Task<string> SendHubMessageAsync(HubMessage message)
|
public async Task<string> SendHubMessageAsync(HubMessage message)
|
||||||
{
|
{
|
||||||
var payload = _protocol.WriteToArray(message);
|
var payload = _protocol.GetMessageBytes(message);
|
||||||
|
|
||||||
await Connection.Application.Output.WriteAsync(payload);
|
await Connection.Application.Output.WriteAsync(payload);
|
||||||
return message is HubInvocationMessage hubMessage ? hubMessage.InvocationId : null;
|
return message is HubInvocationMessage hubMessage ? hubMessage.InvocationId : null;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue