Removed EndOfMessage from Message (#513)
* Removed EndOfMessage from Message - The webSockets transport no longer supports partial payloads so this feature is now gone.
This commit is contained in:
parent
eee2683b5e
commit
42e2715a95
|
|
@ -45,7 +45,7 @@ namespace SocialWeather
|
||||||
? MessageType.Binary
|
? MessageType.Binary
|
||||||
: MessageType.Text;
|
: MessageType.Text;
|
||||||
|
|
||||||
connection.Transport.Output.TryWrite(new Message(ms.ToArray(), format, endOfMessage: true));
|
connection.Transport.Output.TryWrite(new Message(ms.ToArray(), format));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ namespace SocketsSample.EndPoints
|
||||||
// We can avoid the copy here but we'll deal with that later
|
// We can avoid the copy here but we'll deal with that later
|
||||||
var text = Encoding.UTF8.GetString(message.Payload);
|
var text = Encoding.UTF8.GetString(message.Payload);
|
||||||
text = $"{connection.ConnectionId}: {text}";
|
text = $"{connection.ConnectionId}: {text}";
|
||||||
await Broadcast(Encoding.UTF8.GetBytes(text), message.Type, message.EndOfMessage);
|
await Broadcast(Encoding.UTF8.GetBytes(text), message.Type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -43,10 +43,10 @@ namespace SocketsSample.EndPoints
|
||||||
|
|
||||||
private Task Broadcast(string text)
|
private Task Broadcast(string text)
|
||||||
{
|
{
|
||||||
return Broadcast(Encoding.UTF8.GetBytes(text), MessageType.Text, endOfMessage: true);
|
return Broadcast(Encoding.UTF8.GetBytes(text), MessageType.Text);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task Broadcast(byte[] payload, MessageType format, bool endOfMessage)
|
private Task Broadcast(byte[] payload, MessageType format)
|
||||||
{
|
{
|
||||||
var tasks = new List<Task>(Connections.Count);
|
var tasks = new List<Task>(Connections.Count);
|
||||||
|
|
||||||
|
|
@ -54,8 +54,7 @@ namespace SocketsSample.EndPoints
|
||||||
{
|
{
|
||||||
tasks.Add(c.Transport.Output.WriteAsync(new Message(
|
tasks.Add(c.Transport.Output.WriteAsync(new Message(
|
||||||
payload,
|
payload,
|
||||||
format,
|
format)));
|
||||||
endOfMessage)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.WhenAll(tasks);
|
return Task.WhenAll(tasks);
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ A transport is required to have the following attributes:
|
||||||
1. Frame-based - Messages have fixed length (as opposed to streaming, where data is just pushed throughout the connection)
|
1. Frame-based - Messages have fixed length (as opposed to streaming, where data is just pushed throughout the connection)
|
||||||
1. Frame Metadata - Able to encode one piece of Frame Metadata
|
1. Frame Metadata - Able to encode one piece of Frame Metadata
|
||||||
* `Type` - Either `Binary` or `Text`.
|
* `Type` - Either `Binary` or `Text`.
|
||||||
1. Able to handle partial messages from the Server application (i.e. where `EndOfMessage` is `false`). The transport can opt to implement this by buffering, since only WebSockets natively supports this functionality.
|
|
||||||
1. Binary-safe - Able to transmit arbitrary binary data, regardless of content
|
1. Binary-safe - Able to transmit arbitrary binary data, regardless of content
|
||||||
1. Text-safe - Able to transmit arbitrary text data, preserving the content. Line-endings must be preserved **but may be converted to a different format**. For example `\r\n` may be converted to `\n`. This is due to quirks in some transports (Server Sent Events). If the exact line-ending needs to be preserved, the data should be sent as a `Binary` message.
|
1. Text-safe - Able to transmit arbitrary text data, preserving the content. Line-endings must be preserved **but may be converted to a different format**. For example `\r\n` may be converted to `\n`. This is due to quirks in some transports (Server Sent Events). If the exact line-ending needs to be preserved, the data should be sent as a `Binary` message.
|
||||||
|
|
||||||
|
|
@ -30,7 +29,7 @@ For the Long-Polling and Server-Sent events transports, there are two additional
|
||||||
|
|
||||||
The WebSockets transport is unique in that it is full duplex, and a persistent connection that can be established in a single operation. As a result, the client is not required to use the `OPTIONS [endpoint-base]` request to establish a connection in advance. It also includes all the necessary metadata in it's own frame metadata.
|
The WebSockets transport is unique in that it is full duplex, and a persistent connection that can be established in a single operation. As a result, the client is not required to use the `OPTIONS [endpoint-base]` request to establish a connection in advance. It also includes all the necessary metadata in it's own frame metadata.
|
||||||
|
|
||||||
The WebSocket transport is activated by making a WebSocket connection to `[endpoint-base]`. The **optional** `connectionId` query string value is used to identify the connection to attach to. If there is no `connectionId` query string value, a new connection is established. If the parameter is specified but there is no connection with the specified ID value, a `404 Not Found` response is returned. Upon receiving this request, the connection is established and the server responds with a WebSocket upgrade (`101 Switching Protocols`) immediately ready for frames to be sent/received. The WebSocket OpCode field is used to indicate the type of the frame (Text or Binary) and the WebSocket "FIN" flag is used to indicate the end of a message.
|
The WebSocket transport is activated by making a WebSocket connection to `[endpoint-base]`. The **optional** `connectionId` query string value is used to identify the connection to attach to. If there is no `connectionId` query string value, a new connection is established. If the parameter is specified but there is no connection with the specified ID value, a `404 Not Found` response is returned. Upon receiving this request, the connection is established and the server responds with a WebSocket upgrade (`101 Switching Protocols`) immediately ready for frames to be sent/received. The WebSocket OpCode field is used to indicate the type of the frame (Text or Binary).
|
||||||
|
|
||||||
Establishing a second WebSocket connection when there is already a WebSocket connection associated with the Endpoints connection is not permitted and will fail with a `409 Conflict` status code.
|
Establishing a second WebSocket connection when there is already a WebSocket connection associated with the Endpoints connection is not permitted and will fail with a `409 Conflict` status code.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -301,7 +301,7 @@ namespace Microsoft.AspNetCore.SignalR.Redis
|
||||||
{
|
{
|
||||||
var protocol = connection.Metadata.Get<IHubProtocol>(HubConnectionMetadataNames.HubProtocol);
|
var protocol = connection.Metadata.Get<IHubProtocol>(HubConnectionMetadataNames.HubProtocol);
|
||||||
var data = await protocol.WriteToArrayAsync(hubMessage);
|
var data = await protocol.WriteToArrayAsync(hubMessage);
|
||||||
var message = new Message(data, protocol.MessageType, endOfMessage: true);
|
var message = new Message(data, protocol.MessageType);
|
||||||
|
|
||||||
while (await connection.Transport.Output.WaitToWriteAsync())
|
while (await connection.Transport.Output.WaitToWriteAsync())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,7 @@ namespace Microsoft.AspNetCore.SignalR
|
||||||
{
|
{
|
||||||
var protocol = connection.Metadata.Get<IHubProtocol>(HubConnectionMetadataNames.HubProtocol);
|
var protocol = connection.Metadata.Get<IHubProtocol>(HubConnectionMetadataNames.HubProtocol);
|
||||||
var payload = await protocol.WriteToArrayAsync(hubMessage);
|
var payload = await protocol.WriteToArrayAsync(hubMessage);
|
||||||
var message = new Message(payload, protocol.MessageType, endOfMessage: true);
|
var message = new Message(payload, protocol.MessageType);
|
||||||
|
|
||||||
while (await connection.Transport.Output.WaitToWriteAsync())
|
while (await connection.Transport.Output.WaitToWriteAsync())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -229,7 +229,7 @@ namespace Microsoft.AspNetCore.SignalR
|
||||||
private async Task SendMessageAsync(ConnectionContext connection, IHubProtocol protocol, HubMessage hubMessage)
|
private async Task SendMessageAsync(ConnectionContext connection, IHubProtocol protocol, HubMessage hubMessage)
|
||||||
{
|
{
|
||||||
var payload = await protocol.WriteToArrayAsync(hubMessage);
|
var payload = await protocol.WriteToArrayAsync(hubMessage);
|
||||||
var message = new Message(payload, protocol.MessageType, endOfMessage: true);
|
var message = new Message(payload, protocol.MessageType);
|
||||||
|
|
||||||
while (await connection.Transport.Output.WaitToWriteAsync())
|
while (await connection.Transport.Output.WaitToWriteAsync())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ namespace Microsoft.AspNetCore.Sockets.Client
|
||||||
logger.LogDebug("Writing '{0}' message to the server", message.Type);
|
logger.LogDebug("Writing '{0}' message to the server", message.Type);
|
||||||
|
|
||||||
var payload = message.Payload ?? Array.Empty<byte>();
|
var payload = message.Payload ?? Array.Empty<byte>();
|
||||||
if (!MessageFormatter.TryWriteMessage(new Message(payload, message.Type, endOfMessage: true), output, format))
|
if (!MessageFormatter.TryWriteMessage(new Message(payload, message.Type), output, format))
|
||||||
{
|
{
|
||||||
// We didn't get any more memory!
|
// We didn't get any more memory!
|
||||||
throw new InvalidOperationException("Unable to write message to pipeline");
|
throw new InvalidOperationException("Unable to write message to pipeline");
|
||||||
|
|
|
||||||
|
|
@ -115,13 +115,13 @@ namespace Microsoft.AspNetCore.Sockets.Client
|
||||||
offset += incomingMessage[i].Count;
|
offset += incomingMessage[i].Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
message = new Message(messageBuffer, messageType, receiveResult.EndOfMessage);
|
message = new Message(messageBuffer, messageType);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var buffer = new byte[incomingMessage[0].Count];
|
var buffer = new byte[incomingMessage[0].Count];
|
||||||
Buffer.BlockCopy(incomingMessage[0].Array, incomingMessage[0].Offset, buffer, 0, incomingMessage[0].Count);
|
Buffer.BlockCopy(incomingMessage[0].Array, incomingMessage[0].Offset, buffer, 0, incomingMessage[0].Count);
|
||||||
message = new Message(buffer, messageType, receiveResult.EndOfMessage);
|
message = new Message(buffer, messageType);
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogInformation("Passing message to application. Payload size: {0}", message.Payload.Length);
|
_logger.LogInformation("Passing message to application. Payload size: {0}", message.Payload.Length);
|
||||||
|
|
|
||||||
|
|
@ -16,14 +16,6 @@ namespace Microsoft.AspNetCore.Sockets.Internal.Formatters
|
||||||
|
|
||||||
public static bool TryWriteMessage(Message message, IOutput output, MessageFormat format)
|
public static bool TryWriteMessage(Message message, IOutput output, MessageFormat format)
|
||||||
{
|
{
|
||||||
if (!message.EndOfMessage)
|
|
||||||
{
|
|
||||||
// This is a truely exceptional condition since we EXPECT callers to have already
|
|
||||||
// buffered incomplete messages and synthesized the correct, complete message before
|
|
||||||
// giving it to us. Hence we throw, instead of returning false.
|
|
||||||
throw new ArgumentException("Cannot format message where endOfMessage is false using this format", nameof(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
return format == MessageFormat.Text ?
|
return format == MessageFormat.Text ?
|
||||||
TextMessageFormatter.TryWriteMessage(message, output) :
|
TextMessageFormatter.TryWriteMessage(message, output) :
|
||||||
BinaryMessageFormatter.TryWriteMessage(message, output);
|
BinaryMessageFormatter.TryWriteMessage(message, output);
|
||||||
|
|
|
||||||
|
|
@ -23,14 +23,6 @@ namespace Microsoft.AspNetCore.Sockets.Internal.Formatters
|
||||||
|
|
||||||
public static bool TryWriteMessage(Message message, IOutput output)
|
public static bool TryWriteMessage(Message message, IOutput output)
|
||||||
{
|
{
|
||||||
if (!message.EndOfMessage)
|
|
||||||
{
|
|
||||||
// This is a truely exceptional condition since we EXPECT callers to have already
|
|
||||||
// buffered incomplete messages and synthesized the correct, complete message before
|
|
||||||
// giving it to us. Hence we throw, instead of returning false.
|
|
||||||
throw new InvalidOperationException("Cannot format message where endOfMessage is false using this format");
|
|
||||||
}
|
|
||||||
|
|
||||||
var typeIndicator = GetTypeIndicator(message.Type);
|
var typeIndicator = GetTypeIndicator(message.Type);
|
||||||
|
|
||||||
// Write the Data Prefix
|
// Write the Data Prefix
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ namespace Microsoft.AspNetCore.Sockets
|
||||||
{
|
{
|
||||||
public struct Message
|
public struct Message
|
||||||
{
|
{
|
||||||
public bool EndOfMessage { get; }
|
|
||||||
public MessageType Type { get; }
|
public MessageType Type { get; }
|
||||||
|
|
||||||
// REVIEW: We need a better primitive to use here. Memory<byte> would be good,
|
// REVIEW: We need a better primitive to use here. Memory<byte> would be good,
|
||||||
|
|
@ -16,12 +15,6 @@ namespace Microsoft.AspNetCore.Sockets
|
||||||
public byte[] Payload { get; }
|
public byte[] Payload { get; }
|
||||||
|
|
||||||
public Message(byte[] payload, MessageType type)
|
public Message(byte[] payload, MessageType type)
|
||||||
: this(payload, type, endOfMessage: true)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public Message(byte[] payload, MessageType type, bool endOfMessage)
|
|
||||||
{
|
{
|
||||||
if (payload == null)
|
if (payload == null)
|
||||||
{
|
{
|
||||||
|
|
@ -29,7 +22,6 @@ namespace Microsoft.AspNetCore.Sockets
|
||||||
}
|
}
|
||||||
|
|
||||||
Type = type;
|
Type = type;
|
||||||
EndOfMessage = endOfMessage;
|
|
||||||
Payload = payload;
|
Payload = payload;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -161,13 +161,13 @@ namespace Microsoft.AspNetCore.Sockets.Transports
|
||||||
offset += incomingMessage[i].Count;
|
offset += incomingMessage[i].Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
message = new Message(messageBuffer, messageType, receiveResult.EndOfMessage);
|
message = new Message(messageBuffer, messageType);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var buffer = new byte[incomingMessage[0].Count];
|
var buffer = new byte[incomingMessage[0].Count];
|
||||||
Buffer.BlockCopy(incomingMessage[0].Array, incomingMessage[0].Offset, buffer, 0, incomingMessage[0].Count);
|
Buffer.BlockCopy(incomingMessage[0].Array, incomingMessage[0].Offset, buffer, 0, incomingMessage[0].Count);
|
||||||
message = new Message(buffer, messageType, receiveResult.EndOfMessage);
|
message = new Message(buffer, messageType);
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogInformation("Passing message to application. Payload size: {length}", message.Payload.Length);
|
_logger.LogInformation("Passing message to application. Payload size: {length}", message.Payload.Length);
|
||||||
|
|
@ -199,11 +199,11 @@ namespace Microsoft.AspNetCore.Sockets.Transports
|
||||||
|
|
||||||
if (_logger.IsEnabled(LogLevel.Debug))
|
if (_logger.IsEnabled(LogLevel.Debug))
|
||||||
{
|
{
|
||||||
_logger.LogDebug("Sending Type: {messageType}, size: {size}, EndOfMessage: {endOfMessage}",
|
_logger.LogDebug("Sending Type: {messageType}, size: {size}",
|
||||||
message.Type, message.EndOfMessage, message.Payload.Length);
|
message.Type, message.Payload.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
await ws.SendAsync(new ArraySegment<byte>(message.Payload), messageType, message.EndOfMessage, CancellationToken.None);
|
await ws.SendAsync(new ArraySegment<byte>(message.Payload), messageType, endOfMessage: true, cancellationToken: CancellationToken.None);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests
|
||||||
throw new InvalidOperationException("Connection must be started before SendAsync can be called");
|
throw new InvalidOperationException("Connection must be started before SendAsync can be called");
|
||||||
}
|
}
|
||||||
|
|
||||||
var message = new Message(data, type, endOfMessage: true);
|
var message = new Message(data, type);
|
||||||
while (await _sentMessages.Out.WaitToWriteAsync(cancellationToken))
|
while (await _sentMessages.Out.WaitToWriteAsync(cancellationToken))
|
||||||
{
|
{
|
||||||
if (_sentMessages.Out.TryWrite(message))
|
if (_sentMessages.Out.TryWrite(message))
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests
|
||||||
var invocationId = GetInvocationId();
|
var invocationId = GetInvocationId();
|
||||||
var payload = await _protocol.WriteToArrayAsync(new InvocationMessage(invocationId, nonBlocking: false, target: methodName, arguments: args));
|
var payload = await _protocol.WriteToArrayAsync(new InvocationMessage(invocationId, nonBlocking: false, target: methodName, arguments: args));
|
||||||
|
|
||||||
await Application.Output.WriteAsync(new Message(payload, _protocol.MessageType, endOfMessage: true));
|
await Application.Output.WriteAsync(new Message(payload, _protocol.MessageType));
|
||||||
|
|
||||||
return invocationId;
|
return invocationId;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,16 +93,5 @@ namespace Microsoft.AspNetCore.Sockets.Tests.Internal.Formatters
|
||||||
|
|
||||||
Assert.Equal(encoded, output.ToArray().Slice(offset).ToArray());
|
Assert.Equal(encoded, output.ToArray().Slice(offset).ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void WriteInvalidMessages()
|
|
||||||
{
|
|
||||||
var message = new Message(new byte[0], MessageType.Binary, endOfMessage: false);
|
|
||||||
var output = new ArrayOutput(chunkSize: 8); // Use small chunks to test Advance/Enlarge and partial payload writing
|
|
||||||
var ex = Assert.Throws<ArgumentException>(() =>
|
|
||||||
MessageFormatter.TryWriteMessage(message, output, MessageFormat.Binary));
|
|
||||||
Assert.Equal($"Cannot format message where endOfMessage is false using this format{Environment.NewLine}Parameter name: message", ex.Message);
|
|
||||||
Assert.Equal("message", ex.ParamName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,16 +10,6 @@ namespace Microsoft.AspNetCore.Sockets.Tests.Internal.Formatters
|
||||||
{
|
{
|
||||||
public class ServerSentEventsMessageFormatterTests
|
public class ServerSentEventsMessageFormatterTests
|
||||||
{
|
{
|
||||||
[Fact]
|
|
||||||
public void WriteInvalidMessages()
|
|
||||||
{
|
|
||||||
var message = new Message(new byte[0], MessageType.Binary, endOfMessage: false);
|
|
||||||
var output = new ArrayOutput(chunkSize: 8); // Use small chunks to test Advance/Enlarge and partial payload writing
|
|
||||||
var ex = Assert.Throws<InvalidOperationException>(() =>
|
|
||||||
ServerSentEventsMessageFormatter.TryWriteMessage(message, output));
|
|
||||||
Assert.Equal("Cannot format message where endOfMessage is false using this format", ex.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("data: T\r\n\r\n", MessageType.Text, "")]
|
[InlineData("data: T\r\n\r\n", MessageType.Text, "")]
|
||||||
[InlineData("data: T\r\ndata: Hello, World\r\n\r\n", MessageType.Text, "Hello, World")]
|
[InlineData("data: T\r\ndata: Hello, World\r\n\r\n", MessageType.Text, "Hello, World")]
|
||||||
|
|
|
||||||
|
|
@ -66,16 +66,5 @@ namespace Microsoft.AspNetCore.Sockets.Tests.Internal.Formatters
|
||||||
|
|
||||||
Assert.Equal(encoded, Encoding.UTF8.GetString(output.ToArray()));
|
Assert.Equal(encoded, Encoding.UTF8.GetString(output.ToArray()));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void WriteInvalidMessages()
|
|
||||||
{
|
|
||||||
var message = new Message(new byte[0], MessageType.Binary, endOfMessage: false);
|
|
||||||
var output = new ArrayOutput(chunkSize: 8); // Use small chunks to test Advance/Enlarge and partial payload writing
|
|
||||||
var ex = Assert.Throws<ArgumentException>(() =>
|
|
||||||
MessageFormatter.TryWriteMessage(message, output, MessageFormat.Text));
|
|
||||||
Assert.Equal($"Cannot format message where endOfMessage is false using this format{Environment.NewLine}Parameter name: message", ex.Message);
|
|
||||||
Assert.Equal("message", ex.ParamName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,12 @@ namespace Microsoft.AspNetCore.Sockets.Tests
|
||||||
{
|
{
|
||||||
public static void AssertMessage(Message message, MessageType messageType, byte[] payload)
|
public static void AssertMessage(Message message, MessageType messageType, byte[] payload)
|
||||||
{
|
{
|
||||||
Assert.True(message.EndOfMessage);
|
|
||||||
Assert.Equal(messageType, message.Type);
|
Assert.Equal(messageType, message.Type);
|
||||||
Assert.Equal(payload, message.Payload);
|
Assert.Equal(payload, message.Payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AssertMessage(Message message, MessageType messageType, string payload)
|
public static void AssertMessage(Message message, MessageType messageType, string payload)
|
||||||
{
|
{
|
||||||
Assert.True(message.EndOfMessage);
|
|
||||||
Assert.Equal(messageType, message.Type);
|
Assert.Equal(messageType, message.Type);
|
||||||
Assert.Equal(payload, Encoding.UTF8.GetString(message.Payload));
|
Assert.Equal(payload, Encoding.UTF8.GetString(message.Payload));
|
||||||
}
|
}
|
||||||
|
|
@ -27,16 +25,14 @@ namespace Microsoft.AspNetCore.Sockets.Tests
|
||||||
{
|
{
|
||||||
return new Message(
|
return new Message(
|
||||||
payload,
|
payload,
|
||||||
type,
|
type);
|
||||||
endOfMessage: true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Message CreateMessage(string payload, MessageType type)
|
public static Message CreateMessage(string payload, MessageType type)
|
||||||
{
|
{
|
||||||
return new Message(
|
return new Message(
|
||||||
Encoding.UTF8.GetBytes(payload),
|
Encoding.UTF8.GetBytes(payload),
|
||||||
type,
|
type);
|
||||||
endOfMessage: true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -458,7 +458,7 @@ namespace Microsoft.AspNetCore.Sockets.Tests
|
||||||
var buffer = Encoding.UTF8.GetBytes("Hello World");
|
var buffer = Encoding.UTF8.GetBytes("Hello World");
|
||||||
|
|
||||||
// Write to the transport so the poll yields
|
// Write to the transport so the poll yields
|
||||||
await state.Connection.Transport.Output.WriteAsync(new Message(buffer, MessageType.Text, endOfMessage: true));
|
await state.Connection.Transport.Output.WriteAsync(new Message(buffer, MessageType.Text));
|
||||||
|
|
||||||
await task;
|
await task;
|
||||||
|
|
||||||
|
|
@ -490,7 +490,7 @@ namespace Microsoft.AspNetCore.Sockets.Tests
|
||||||
var buffer = Encoding.UTF8.GetBytes("Hello World");
|
var buffer = Encoding.UTF8.GetBytes("Hello World");
|
||||||
|
|
||||||
// Write to the application
|
// Write to the application
|
||||||
await state.Application.Output.WriteAsync(new Message(buffer, MessageType.Text, endOfMessage: true));
|
await state.Application.Output.WriteAsync(new Message(buffer, MessageType.Text));
|
||||||
|
|
||||||
await task;
|
await task;
|
||||||
|
|
||||||
|
|
@ -521,7 +521,7 @@ namespace Microsoft.AspNetCore.Sockets.Tests
|
||||||
var buffer = Encoding.UTF8.GetBytes("Hello World");
|
var buffer = Encoding.UTF8.GetBytes("Hello World");
|
||||||
|
|
||||||
// Write to the application
|
// Write to the application
|
||||||
await state.Application.Output.WriteAsync(new Message(buffer, MessageType.Text, endOfMessage: true));
|
await state.Application.Output.WriteAsync(new Message(buffer, MessageType.Text));
|
||||||
|
|
||||||
await task;
|
await task;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,7 @@ namespace Microsoft.AspNetCore.Sockets.Tests
|
||||||
|
|
||||||
await channel.Out.WriteAsync(new Message(
|
await channel.Out.WriteAsync(new Message(
|
||||||
Encoding.UTF8.GetBytes("Hello World"),
|
Encoding.UTF8.GetBytes("Hello World"),
|
||||||
MessageType.Text,
|
MessageType.Text));
|
||||||
endOfMessage: true));
|
|
||||||
|
|
||||||
Assert.True(channel.Out.TryComplete());
|
Assert.True(channel.Out.TryComplete());
|
||||||
|
|
||||||
|
|
@ -70,16 +69,13 @@ namespace Microsoft.AspNetCore.Sockets.Tests
|
||||||
|
|
||||||
await channel.Out.WriteAsync(new Message(
|
await channel.Out.WriteAsync(new Message(
|
||||||
Encoding.UTF8.GetBytes("Hello"),
|
Encoding.UTF8.GetBytes("Hello"),
|
||||||
MessageType.Text,
|
MessageType.Text));
|
||||||
endOfMessage: true));
|
|
||||||
await channel.Out.WriteAsync(new Message(
|
await channel.Out.WriteAsync(new Message(
|
||||||
Encoding.UTF8.GetBytes(" "),
|
Encoding.UTF8.GetBytes(" "),
|
||||||
MessageType.Text,
|
MessageType.Text));
|
||||||
endOfMessage: true));
|
|
||||||
await channel.Out.WriteAsync(new Message(
|
await channel.Out.WriteAsync(new Message(
|
||||||
Encoding.UTF8.GetBytes("World"),
|
Encoding.UTF8.GetBytes("World"),
|
||||||
MessageType.Text,
|
MessageType.Text));
|
||||||
endOfMessage: true));
|
|
||||||
|
|
||||||
Assert.True(channel.Out.TryComplete());
|
Assert.True(channel.Out.TryComplete());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,8 +62,7 @@ namespace Microsoft.AspNetCore.Sockets.Tests
|
||||||
|
|
||||||
await channel.Out.WriteAsync(new Message(
|
await channel.Out.WriteAsync(new Message(
|
||||||
Encoding.UTF8.GetBytes(message),
|
Encoding.UTF8.GetBytes(message),
|
||||||
MessageType.Text,
|
MessageType.Text));
|
||||||
endOfMessage: true));
|
|
||||||
|
|
||||||
Assert.True(channel.Out.TryComplete());
|
Assert.True(channel.Out.TryComplete());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,6 @@ namespace Microsoft.AspNetCore.Sockets.Tests
|
||||||
await feature.Client.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
|
await feature.Client.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
|
||||||
|
|
||||||
var message = await applicationSide.Input.In.ReadAsync();
|
var message = await applicationSide.Input.In.ReadAsync();
|
||||||
Assert.True(message.EndOfMessage);
|
|
||||||
Assert.Equal(format, message.Type);
|
Assert.Equal(format, message.Type);
|
||||||
Assert.Equal("Hello", Encoding.UTF8.GetString(message.Payload));
|
Assert.Equal("Hello", Encoding.UTF8.GetString(message.Payload));
|
||||||
|
|
||||||
|
|
@ -63,53 +62,6 @@ namespace Microsoft.AspNetCore.Sockets.Tests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(MessageType.Text, WebSocketMessageType.Text)]
|
|
||||||
[InlineData(MessageType.Binary, WebSocketMessageType.Binary)]
|
|
||||||
public async Task IncompleteMessagesAreWrittenAsMultiFrameWebSocketMessages(MessageType format, WebSocketMessageType webSocketMessageType)
|
|
||||||
{
|
|
||||||
var transportToApplication = Channel.CreateUnbounded<Message>();
|
|
||||||
var applicationToTransport = Channel.CreateUnbounded<Message>();
|
|
||||||
|
|
||||||
var transportSide = new ChannelConnection<Message>(applicationToTransport, transportToApplication);
|
|
||||||
var applicationSide = new ChannelConnection<Message>(transportToApplication, applicationToTransport);
|
|
||||||
|
|
||||||
using (var feature = new TestWebSocketConnectionFeature())
|
|
||||||
{
|
|
||||||
var ws = new WebSocketsTransport(new WebSocketOptions(), transportSide, new LoggerFactory());
|
|
||||||
|
|
||||||
// Give the server socket to the transport and run it
|
|
||||||
var transport = ws.ProcessSocketAsync(await feature.AcceptAsync());
|
|
||||||
|
|
||||||
// Run the client socket
|
|
||||||
var client = feature.Client.ExecuteAndCaptureFramesAsync();
|
|
||||||
|
|
||||||
// Write multi-frame message to the output channel, and then complete it
|
|
||||||
await applicationSide.Output.Out.WriteAsync(new Message(
|
|
||||||
Encoding.UTF8.GetBytes("Hello"),
|
|
||||||
format,
|
|
||||||
endOfMessage: false));
|
|
||||||
await applicationSide.Output.Out.WriteAsync(new Message(
|
|
||||||
Encoding.UTF8.GetBytes("World"),
|
|
||||||
format,
|
|
||||||
endOfMessage: true));
|
|
||||||
Assert.True(applicationSide.Output.Out.TryComplete());
|
|
||||||
|
|
||||||
// The client should finish now, as should the server
|
|
||||||
var clientSummary = await client;
|
|
||||||
await feature.Client.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
|
|
||||||
await transport;
|
|
||||||
|
|
||||||
Assert.Equal(2, clientSummary.Received.Count);
|
|
||||||
Assert.False(clientSummary.Received[0].EndOfMessage);
|
|
||||||
Assert.Equal(webSocketMessageType, clientSummary.Received[0].MessageType);
|
|
||||||
Assert.Equal("Hello", Encoding.UTF8.GetString(clientSummary.Received[0].Buffer));
|
|
||||||
Assert.True(clientSummary.Received[1].EndOfMessage);
|
|
||||||
Assert.Equal(webSocketMessageType, clientSummary.Received[1].MessageType);
|
|
||||||
Assert.Equal("World", Encoding.UTF8.GetString(clientSummary.Received[1].Buffer));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData(MessageType.Text, WebSocketMessageType.Text)]
|
[InlineData(MessageType.Text, WebSocketMessageType.Text)]
|
||||||
[InlineData(MessageType.Binary, WebSocketMessageType.Binary)]
|
[InlineData(MessageType.Binary, WebSocketMessageType.Binary)]
|
||||||
|
|
@ -134,8 +86,7 @@ namespace Microsoft.AspNetCore.Sockets.Tests
|
||||||
// Write to the output channel, and then complete it
|
// Write to the output channel, and then complete it
|
||||||
await applicationSide.Output.Out.WriteAsync(new Message(
|
await applicationSide.Output.Out.WriteAsync(new Message(
|
||||||
Encoding.UTF8.GetBytes("Hello"),
|
Encoding.UTF8.GetBytes("Hello"),
|
||||||
format,
|
format));
|
||||||
endOfMessage: true));
|
|
||||||
Assert.True(applicationSide.Output.Out.TryComplete());
|
Assert.True(applicationSide.Output.Out.TryComplete());
|
||||||
|
|
||||||
// The client should finish now, as should the server
|
// The client should finish now, as should the server
|
||||||
|
|
@ -185,7 +136,6 @@ namespace Microsoft.AspNetCore.Sockets.Tests
|
||||||
|
|
||||||
// Read that frame from the input
|
// Read that frame from the input
|
||||||
var message = await applicationSide.Input.In.ReadAsync();
|
var message = await applicationSide.Input.In.ReadAsync();
|
||||||
Assert.True(message.EndOfMessage);
|
|
||||||
Assert.Equal(format, message.Type);
|
Assert.Equal(format, message.Type);
|
||||||
Assert.Equal("Hello", Encoding.UTF8.GetString(message.Payload));
|
Assert.Equal("Hello", Encoding.UTF8.GetString(message.Payload));
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue