Server: Expose WebSocketOptions. Make feature replacement configurable.
This commit is contained in:
parent
b24d808b58
commit
df425e4796
|
|
@ -25,8 +25,10 @@
|
||||||
<SchemaVersion>2.0</SchemaVersion>
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="WebSocketAcceptContext.cs" />
|
||||||
<Compile Include="WebSocketMiddleware.cs" />
|
<Compile Include="WebSocketMiddleware.cs" />
|
||||||
<Compile Include="WebSocketMiddlewareExtensions.cs" />
|
<Compile Include="WebSocketMiddlewareExtensions.cs" />
|
||||||
|
<Compile Include="WebSocketOptions.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="project.json" />
|
<Content Include="project.json" />
|
||||||
|
|
|
||||||
|
|
@ -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
|
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;
|
_next = next;
|
||||||
|
_options = options;
|
||||||
|
|
||||||
|
// TODO: validate options.
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task Invoke(HttpContext context)
|
public Task Invoke(HttpContext context)
|
||||||
{
|
{
|
||||||
// Detect if an opaque upgrade is available, and if websocket upgrade headers are present.
|
// Detect if an opaque upgrade is available. If so, add a websocket upgrade.
|
||||||
// If so, add a websocket upgrade.
|
|
||||||
var upgradeFeature = context.GetFeature<IHttpOpaqueUpgradeFeature>();
|
var upgradeFeature = context.GetFeature<IHttpOpaqueUpgradeFeature>();
|
||||||
if (upgradeFeature != null)
|
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);
|
return _next(context);
|
||||||
|
|
@ -37,13 +43,15 @@ namespace Microsoft.AspNet.WebSockets.Server
|
||||||
|
|
||||||
private class UpgradeHandshake : IHttpWebSocketFeature
|
private class UpgradeHandshake : IHttpWebSocketFeature
|
||||||
{
|
{
|
||||||
private HttpContext _context;
|
private readonly HttpContext _context;
|
||||||
private IHttpOpaqueUpgradeFeature _upgradeFeature;
|
private readonly IHttpOpaqueUpgradeFeature _upgradeFeature;
|
||||||
|
private readonly WebSocketOptions _options;
|
||||||
|
|
||||||
public UpgradeHandshake(HttpContext context, IHttpOpaqueUpgradeFeature upgradeFeature)
|
public UpgradeHandshake(HttpContext context, IHttpOpaqueUpgradeFeature upgradeFeature, WebSocketOptions options)
|
||||||
{
|
{
|
||||||
_context = context;
|
_context = context;
|
||||||
_upgradeFeature = upgradeFeature;
|
_upgradeFeature = upgradeFeature;
|
||||||
|
_options = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsWebSocketRequest
|
public bool IsWebSocketRequest
|
||||||
|
|
@ -70,7 +78,7 @@ namespace Microsoft.AspNet.WebSockets.Server
|
||||||
{
|
{
|
||||||
if (!IsWebSocketRequest)
|
if (!IsWebSocketRequest)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("Not a WebSocket request.");
|
throw new InvalidOperationException("Not a WebSocket request."); // TODO: LOC
|
||||||
}
|
}
|
||||||
|
|
||||||
string subProtocol = null;
|
string subProtocol = null;
|
||||||
|
|
@ -79,8 +87,8 @@ namespace Microsoft.AspNet.WebSockets.Server
|
||||||
subProtocol = acceptContext.SubProtocol;
|
subProtocol = acceptContext.SubProtocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeSpan keepAliveInterval = TimeSpan.FromMinutes(2); // TODO:
|
TimeSpan keepAliveInterval = _options.KeepAliveInterval;
|
||||||
int receiveBufferSize = 4 * 1024; // TODO:
|
int receiveBufferSize = _options.ReceiveBufferSize;
|
||||||
var advancedAcceptContext = acceptContext as WebSocketAcceptContext;
|
var advancedAcceptContext = acceptContext as WebSocketAcceptContext;
|
||||||
if (advancedAcceptContext != null)
|
if (advancedAcceptContext != null)
|
||||||
{
|
{
|
||||||
|
|
@ -106,13 +114,5 @@ namespace Microsoft.AspNet.WebSockets.Server
|
||||||
return CommonWebSocket.CreateServerWebSocket(opaqueTransport, subProtocol, keepAliveInterval, receiveBufferSize);
|
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)
|
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