diff --git a/src/Microsoft.AspNet.WebSockets.Server/Microsoft.AspNet.WebSockets.Server.kproj b/src/Microsoft.AspNet.WebSockets.Server/Microsoft.AspNet.WebSockets.Server.kproj index 89ca756f23..8c7033f08b 100644 --- a/src/Microsoft.AspNet.WebSockets.Server/Microsoft.AspNet.WebSockets.Server.kproj +++ b/src/Microsoft.AspNet.WebSockets.Server/Microsoft.AspNet.WebSockets.Server.kproj @@ -25,11 +25,13 @@ 2.0 + + - + \ No newline at end of file diff --git a/src/Microsoft.AspNet.WebSockets.Server/WebSocketAcceptContext.cs b/src/Microsoft.AspNet.WebSockets.Server/WebSocketAcceptContext.cs new file mode 100644 index 0000000000..0762d79eff --- /dev/null +++ b/src/Microsoft.AspNet.WebSockets.Server/WebSocketAcceptContext.cs @@ -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? Buffer { get; set; } // TODO + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.WebSockets.Server/WebSocketMiddleware.cs b/src/Microsoft.AspNet.WebSockets.Server/WebSocketMiddleware.cs index 44825a9897..2a2077cfdc 100644 --- a/src/Microsoft.AspNet.WebSockets.Server/WebSocketMiddleware.cs +++ b/src/Microsoft.AspNet.WebSockets.Server/WebSocketMiddleware.cs @@ -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(); if (upgradeFeature != null) { - context.SetFeature(new UpgradeHandshake(context, upgradeFeature)); + if (_options.ReplaceFeature || context.GetFeature() == null) + { + context.SetFeature(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? Buffer { get; set; } // TODO - } } } diff --git a/src/Microsoft.AspNet.WebSockets.Server/WebSocketMiddlewareExtensions.cs b/src/Microsoft.AspNet.WebSockets.Server/WebSocketMiddlewareExtensions.cs index 584ca3abc1..8dd1559d23 100644 --- a/src/Microsoft.AspNet.WebSockets.Server/WebSocketMiddlewareExtensions.cs +++ b/src/Microsoft.AspNet.WebSockets.Server/WebSocketMiddlewareExtensions.cs @@ -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); } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.WebSockets.Server/WebSocketOptions.cs b/src/Microsoft.AspNet.WebSockets.Server/WebSocketOptions.cs new file mode 100644 index 0000000000..5f46a23558 --- /dev/null +++ b/src/Microsoft.AspNet.WebSockets.Server/WebSocketOptions.cs @@ -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 +{ + /// + /// Configuration options for the WebSocketMiddleware + /// + public class WebSocketOptions + { + public WebSocketOptions() + { + KeepAliveInterval = TimeSpan.FromMinutes(2); + ReceiveBufferSize = 4 * 1024; + ReplaceFeature = false; + } + + /// + /// Gets or sets the frequency at which to send Ping/Pong keep-alive control frames. + /// The default is two minutes. + /// + public TimeSpan KeepAliveInterval { get; set; } + + /// + /// Gets or sets the size of the protocol buffer used to receive and parse frames. + /// The default is 4kb. + /// + public int ReceiveBufferSize { get; set; } + + /// + /// Gets or sets if the middleware should replace the WebSocket implementation provided by + /// a component earlier in the stack. This is false by default. + /// + public bool ReplaceFeature { get; set; } + } +} \ No newline at end of file