Server: Expose WebSocketOptions. Make feature replacement configurable.
This commit is contained in:
parent
b24d808b58
commit
df425e4796
|
|
@ -25,11 +25,13 @@
|
|||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="WebSocketAcceptContext.cs" />
|
||||
<Compile Include="WebSocketMiddleware.cs" />
|
||||
<Compile Include="WebSocketMiddlewareExtensions.cs" />
|
||||
<Compile Include="WebSocketOptions.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="project.json" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNet.HttpFeature;
|
||||
|
||||
namespace Microsoft.AspNet.WebSockets.Server
|
||||
{
|
||||
public class WebSocketAcceptContext : IWebSocketAcceptContext
|
||||
{
|
||||
public string SubProtocol { get; set; }
|
||||
public int? ReceiveBufferSize { get; set; }
|
||||
public TimeSpan? KeepAliveInterval { get; set; }
|
||||
|
||||
// public ArraySegment<byte>? Buffer { get; set; } // TODO
|
||||
}
|
||||
}
|
||||
|
|
@ -15,21 +15,27 @@ namespace Microsoft.AspNet.WebSockets.Server
|
|||
{
|
||||
public class WebSocketMiddleware
|
||||
{
|
||||
private RequestDelegate _next;
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly WebSocketOptions _options;
|
||||
|
||||
public WebSocketMiddleware(RequestDelegate next)
|
||||
public WebSocketMiddleware(RequestDelegate next, WebSocketOptions options)
|
||||
{
|
||||
_next = next;
|
||||
_options = options;
|
||||
|
||||
// TODO: validate options.
|
||||
}
|
||||
|
||||
public Task Invoke(HttpContext context)
|
||||
{
|
||||
// Detect if an opaque upgrade is available, and if websocket upgrade headers are present.
|
||||
// If so, add a websocket upgrade.
|
||||
// Detect if an opaque upgrade is available. If so, add a websocket upgrade.
|
||||
var upgradeFeature = context.GetFeature<IHttpOpaqueUpgradeFeature>();
|
||||
if (upgradeFeature != null)
|
||||
{
|
||||
context.SetFeature<IHttpWebSocketFeature>(new UpgradeHandshake(context, upgradeFeature));
|
||||
if (_options.ReplaceFeature || context.GetFeature<IHttpWebSocketFeature>() == null)
|
||||
{
|
||||
context.SetFeature<IHttpWebSocketFeature>(new UpgradeHandshake(context, upgradeFeature, _options));
|
||||
}
|
||||
}
|
||||
|
||||
return _next(context);
|
||||
|
|
@ -37,13 +43,15 @@ namespace Microsoft.AspNet.WebSockets.Server
|
|||
|
||||
private class UpgradeHandshake : IHttpWebSocketFeature
|
||||
{
|
||||
private HttpContext _context;
|
||||
private IHttpOpaqueUpgradeFeature _upgradeFeature;
|
||||
private readonly HttpContext _context;
|
||||
private readonly IHttpOpaqueUpgradeFeature _upgradeFeature;
|
||||
private readonly WebSocketOptions _options;
|
||||
|
||||
public UpgradeHandshake(HttpContext context, IHttpOpaqueUpgradeFeature upgradeFeature)
|
||||
public UpgradeHandshake(HttpContext context, IHttpOpaqueUpgradeFeature upgradeFeature, WebSocketOptions options)
|
||||
{
|
||||
_context = context;
|
||||
_upgradeFeature = upgradeFeature;
|
||||
_options = options;
|
||||
}
|
||||
|
||||
public bool IsWebSocketRequest
|
||||
|
|
@ -70,7 +78,7 @@ namespace Microsoft.AspNet.WebSockets.Server
|
|||
{
|
||||
if (!IsWebSocketRequest)
|
||||
{
|
||||
throw new InvalidOperationException("Not a WebSocket request.");
|
||||
throw new InvalidOperationException("Not a WebSocket request."); // TODO: LOC
|
||||
}
|
||||
|
||||
string subProtocol = null;
|
||||
|
|
@ -79,8 +87,8 @@ namespace Microsoft.AspNet.WebSockets.Server
|
|||
subProtocol = acceptContext.SubProtocol;
|
||||
}
|
||||
|
||||
TimeSpan keepAliveInterval = TimeSpan.FromMinutes(2); // TODO:
|
||||
int receiveBufferSize = 4 * 1024; // TODO:
|
||||
TimeSpan keepAliveInterval = _options.KeepAliveInterval;
|
||||
int receiveBufferSize = _options.ReceiveBufferSize;
|
||||
var advancedAcceptContext = acceptContext as WebSocketAcceptContext;
|
||||
if (advancedAcceptContext != null)
|
||||
{
|
||||
|
|
@ -106,13 +114,5 @@ namespace Microsoft.AspNet.WebSockets.Server
|
|||
return CommonWebSocket.CreateServerWebSocket(opaqueTransport, subProtocol, keepAliveInterval, receiveBufferSize);
|
||||
}
|
||||
}
|
||||
|
||||
public class WebSocketAcceptContext : IWebSocketAcceptContext
|
||||
{
|
||||
public string SubProtocol { get; set; }
|
||||
public int? ReceiveBufferSize { get; set; }
|
||||
public TimeSpan? KeepAliveInterval { get; set; }
|
||||
// public ArraySegment<byte>? Buffer { get; set; } // TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,12 @@ namespace Microsoft.AspNet.Builder
|
|||
{
|
||||
public static IBuilder UseWebSockets(this IBuilder builder)
|
||||
{
|
||||
return builder.Use(next => new WebSocketMiddleware(next).Invoke);
|
||||
return builder.UseWebSockets(new WebSocketOptions());
|
||||
}
|
||||
|
||||
public static IBuilder UseWebSockets(this IBuilder builder, WebSocketOptions options) // TODO: [NotNull]
|
||||
{
|
||||
return builder.Use(next => new WebSocketMiddleware(next, options).Invoke);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.AspNet.WebSockets.Server
|
||||
{
|
||||
/// <summary>
|
||||
/// Configuration options for the WebSocketMiddleware
|
||||
/// </summary>
|
||||
public class WebSocketOptions
|
||||
{
|
||||
public WebSocketOptions()
|
||||
{
|
||||
KeepAliveInterval = TimeSpan.FromMinutes(2);
|
||||
ReceiveBufferSize = 4 * 1024;
|
||||
ReplaceFeature = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the frequency at which to send Ping/Pong keep-alive control frames.
|
||||
/// The default is two minutes.
|
||||
/// </summary>
|
||||
public TimeSpan KeepAliveInterval { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the size of the protocol buffer used to receive and parse frames.
|
||||
/// The default is 4kb.
|
||||
/// </summary>
|
||||
public int ReceiveBufferSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets if the middleware should replace the WebSocket implementation provided by
|
||||
/// a component earlier in the stack. This is false by default.
|
||||
/// </summary>
|
||||
public bool ReplaceFeature { get; set; }
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue