@davidfowl love dat Func<...,object,...>,object pattern
This commit is contained in:
parent
a1c0970222
commit
d2dbd473a0
|
|
@ -48,8 +48,9 @@ namespace Microsoft.Extensions.WebSockets
|
||||||
/// Runs the WebSocket receive loop, using the provided message handler.
|
/// Runs the WebSocket receive loop, using the provided message handler.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="messageHandler">The callback that will be invoked for each new frame</param>
|
/// <param name="messageHandler">The callback that will be invoked for each new frame</param>
|
||||||
|
/// <param name="state">A state parameter that will be passed to each invocation of <paramref name="messageHandler"/></param>
|
||||||
/// <returns>A <see cref="Task{WebSocketCloseResult}"/> that will complete when the client has sent a close frame, or the connection has been terminated</returns>
|
/// <returns>A <see cref="Task{WebSocketCloseResult}"/> that will complete when the client has sent a close frame, or the connection has been terminated</returns>
|
||||||
Task<WebSocketCloseResult> ExecuteAsync(Func<WebSocketFrame, Task> messageHandler);
|
Task<WebSocketCloseResult> ExecuteAsync(Func<WebSocketFrame, object, Task> messageHandler, object state);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class WebSocketConnectionExtensions
|
public static class WebSocketConnectionExtensions
|
||||||
|
|
@ -74,9 +75,28 @@ namespace Microsoft.Extensions.WebSockets
|
||||||
/// <param name="messageHandler">The callback that will be invoked for each new frame</param>
|
/// <param name="messageHandler">The callback that will be invoked for each new frame</param>
|
||||||
/// <returns>A <see cref="Task{WebSocketCloseResult}"/> that will complete when the client has sent a close frame, or the connection has been terminated</returns>
|
/// <returns>A <see cref="Task{WebSocketCloseResult}"/> that will complete when the client has sent a close frame, or the connection has been terminated</returns>
|
||||||
public static Task<WebSocketCloseResult> ExecuteAsync(this IWebSocketConnection self, Action<WebSocketFrame> messageHandler) =>
|
public static Task<WebSocketCloseResult> ExecuteAsync(this IWebSocketConnection self, Action<WebSocketFrame> messageHandler) =>
|
||||||
self.ExecuteAsync(frame => {
|
self.ExecuteAsync((frame, _) => {
|
||||||
messageHandler(frame);
|
messageHandler(frame);
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
});
|
}, null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Runs the WebSocket receive loop, using the provided message handler.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="messageHandler">The callback that will be invoked for each new frame</param>
|
||||||
|
/// <returns>A <see cref="Task{WebSocketCloseResult}"/> that will complete when the client has sent a close frame, or the connection has been terminated</returns>
|
||||||
|
public static Task<WebSocketCloseResult> ExecuteAsync(this IWebSocketConnection self, Action<WebSocketFrame, object> messageHandler, object state) =>
|
||||||
|
self.ExecuteAsync((frame, s) => {
|
||||||
|
messageHandler(frame, s);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}, state);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Runs the WebSocket receive loop, using the provided message handler.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="messageHandler">The callback that will be invoked for each new frame</param>
|
||||||
|
/// <returns>A <see cref="Task{WebSocketCloseResult}"/> that will complete when the client has sent a close frame, or the connection has been terminated</returns>
|
||||||
|
public static Task<WebSocketCloseResult> ExecuteAsync(this IWebSocketConnection self, Func<WebSocketFrame, Task> messageHandler) =>
|
||||||
|
self.ExecuteAsync((frame, _) => messageHandler(frame), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,13 +34,13 @@ namespace Microsoft.Extensions.WebSockets
|
||||||
|
|
||||||
public static bool TryParse(ReadableBuffer payload, out WebSocketCloseResult result)
|
public static bool TryParse(ReadableBuffer payload, out WebSocketCloseResult result)
|
||||||
{
|
{
|
||||||
if(payload.Length == 0)
|
if (payload.Length == 0)
|
||||||
{
|
{
|
||||||
// Empty payload is OK
|
// Empty payload is OK
|
||||||
result = new WebSocketCloseResult(WebSocketCloseStatus.Empty, string.Empty);
|
result = new WebSocketCloseResult(WebSocketCloseStatus.Empty, string.Empty);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if(payload.Length < 2)
|
else if (payload.Length < 2)
|
||||||
{
|
{
|
||||||
result = default(WebSocketCloseResult);
|
result = default(WebSocketCloseResult);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -50,7 +50,7 @@ namespace Microsoft.Extensions.WebSockets
|
||||||
var status = payload.ReadBigEndian<ushort>();
|
var status = payload.ReadBigEndian<ushort>();
|
||||||
var description = string.Empty;
|
var description = string.Empty;
|
||||||
payload = payload.Slice(2);
|
payload = payload.Slice(2);
|
||||||
if(payload.Length > 0)
|
if (payload.Length > 0)
|
||||||
{
|
{
|
||||||
description = payload.GetUtf8String();
|
description = payload.GetUtf8String();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ namespace Microsoft.Extensions.WebSockets
|
||||||
_terminateReceiveCts.Cancel();
|
_terminateReceiveCts.Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<WebSocketCloseResult> ExecuteAsync(Func<WebSocketFrame, Task> messageHandler)
|
public Task<WebSocketCloseResult> ExecuteAsync(Func<WebSocketFrame, object, Task> messageHandler, object state)
|
||||||
{
|
{
|
||||||
if (State == WebSocketConnectionState.Closed)
|
if (State == WebSocketConnectionState.Closed)
|
||||||
{
|
{
|
||||||
|
|
@ -91,7 +91,7 @@ namespace Microsoft.Extensions.WebSockets
|
||||||
throw new InvalidOperationException("Connection is already running.");
|
throw new InvalidOperationException("Connection is already running.");
|
||||||
}
|
}
|
||||||
State = WebSocketConnectionState.Connected;
|
State = WebSocketConnectionState.Connected;
|
||||||
return Task.Run(() => ReceiveLoop(messageHandler, _terminateReceiveCts.Token));
|
return ReceiveLoop(messageHandler, state, _terminateReceiveCts.Token);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -177,7 +177,7 @@ namespace Microsoft.Extensions.WebSockets
|
||||||
buffer.Set(_maskingKey);
|
buffer.Set(_maskingKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<WebSocketCloseResult> ReceiveLoop(Func<WebSocketFrame, Task> messageHandler, CancellationToken cancellationToken)
|
private async Task<WebSocketCloseResult> ReceiveLoop(Func<WebSocketFrame, object, Task> messageHandler, object state, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
while (!cancellationToken.IsCancellationRequested)
|
while (!cancellationToken.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
|
|
@ -309,7 +309,7 @@ namespace Microsoft.Extensions.WebSockets
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await messageHandler(frame);
|
await messageHandler(frame, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark the payload as consumed
|
// Mark the payload as consumed
|
||||||
|
|
@ -376,6 +376,7 @@ namespace Microsoft.Extensions.WebSockets
|
||||||
|
|
||||||
// Allocate a buffer
|
// Allocate a buffer
|
||||||
var buffer = _outbound.Alloc(minimumSize: allocSize);
|
var buffer = _outbound.Alloc(minimumSize: allocSize);
|
||||||
|
Debug.Assert(buffer.Memory.Length >= allocSize);
|
||||||
if (buffer.Memory.Length < allocSize)
|
if (buffer.Memory.Length < allocSize)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("Couldn't allocate enough data from the channel to write the header");
|
throw new InvalidOperationException("Couldn't allocate enough data from the channel to write the header");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue