From 8ce3e74e8112a94773df22827849bf274fc88198 Mon Sep 17 00:00:00 2001 From: LukePulverenti Date: Sun, 24 Feb 2013 16:53:54 -0500 Subject: More DI --- .../MediaBrowser.Networking.csproj | 2 + MediaBrowser.Networking/Web/HttpServer.cs | 21 ++- MediaBrowser.Networking/Web/NativeWebSocket.cs | 145 +++++++++++++++++++++ MediaBrowser.Networking/Web/ServerFactory.cs | 28 ++++ .../WebSocket/AlchemyWebSocket.cs | 8 +- 5 files changed, 198 insertions(+), 6 deletions(-) create mode 100644 MediaBrowser.Networking/Web/NativeWebSocket.cs create mode 100644 MediaBrowser.Networking/Web/ServerFactory.cs (limited to 'MediaBrowser.Networking') diff --git a/MediaBrowser.Networking/MediaBrowser.Networking.csproj b/MediaBrowser.Networking/MediaBrowser.Networking.csproj index 7e4a0b1608..41fd6ceab4 100644 --- a/MediaBrowser.Networking/MediaBrowser.Networking.csproj +++ b/MediaBrowser.Networking/MediaBrowser.Networking.csproj @@ -112,6 +112,8 @@ + + diff --git a/MediaBrowser.Networking/Web/HttpServer.cs b/MediaBrowser.Networking/Web/HttpServer.cs index c280abedf1..ab4b8558f7 100644 --- a/MediaBrowser.Networking/Web/HttpServer.cs +++ b/MediaBrowser.Networking/Web/HttpServer.cs @@ -4,6 +4,7 @@ using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Kernel; using MediaBrowser.Common.Net; using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Serialization; using ServiceStack.Api.Swagger; using ServiceStack.Common.Web; using ServiceStack.Configuration; @@ -60,6 +61,12 @@ namespace MediaBrowser.Networking.Web /// The HTTP listener. private IDisposable HttpListener { get; set; } + /// + /// Gets or sets the protobuf serializer. + /// + /// The protobuf serializer. + private IProtobufSerializer ProtobufSerializer { get; set; } + /// /// Occurs when [web socket connected]. /// @@ -82,17 +89,22 @@ namespace MediaBrowser.Networking.Web /// /// The application host. /// The kernel. + /// The protobuf serializer. /// The logger. /// Name of the server. /// The default redirectpath. /// urlPrefix - public HttpServer(IApplicationHost applicationHost, IKernel kernel, ILogger logger, string serverName, string defaultRedirectpath) + public HttpServer(IApplicationHost applicationHost, IKernel kernel, IProtobufSerializer protobufSerializer, ILogger logger, string serverName, string defaultRedirectpath) : base() { if (kernel == null) { throw new ArgumentNullException("kernel"); } + if (protobufSerializer == null) + { + throw new ArgumentNullException("protobufSerializer"); + } if (logger == null) { throw new ArgumentNullException("logger"); @@ -112,6 +124,7 @@ namespace MediaBrowser.Networking.Web ServerName = serverName; DefaultRedirectPath = defaultRedirectpath; + ProtobufSerializer = protobufSerializer; _logger = logger; ApplicationHost = applicationHost; @@ -121,7 +134,7 @@ namespace MediaBrowser.Networking.Web Kernel = kernel; EndpointHost.ConfigureHost(this, ServerName, CreateServiceManager()); - ContentTypeFilters.Register(ContentType.ProtoBuf, (reqCtx, res, stream) => Kernel.ProtobufSerializer.SerializeToStream(res, stream), (type, stream) => Kernel.ProtobufSerializer.DeserializeFromStream(stream, type)); + ContentTypeFilters.Register(ContentType.ProtoBuf, (reqCtx, res, stream) => ProtobufSerializer.SerializeToStream(res, stream), (type, stream) => ProtobufSerializer.DeserializeFromStream(stream, type)); Init(); } @@ -132,6 +145,10 @@ namespace MediaBrowser.Networking.Web /// The container. public override void Configure(Container container) { + JsConfig.DateHandler = JsonDateHandler.ISO8601; + JsConfig.ExcludeTypeInfo = true; + JsConfig.IncludeNullValues = false; + SetConfig(new EndpointHostConfig { DefaultRedirectPath = DefaultRedirectPath, diff --git a/MediaBrowser.Networking/Web/NativeWebSocket.cs b/MediaBrowser.Networking/Web/NativeWebSocket.cs new file mode 100644 index 0000000000..ad28d1a7f7 --- /dev/null +++ b/MediaBrowser.Networking/Web/NativeWebSocket.cs @@ -0,0 +1,145 @@ +using MediaBrowser.Model.Logging; +using System; +using System.Net.WebSockets; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Common.Net +{ + /// + /// Class NativeWebSocket + /// + public class NativeWebSocket : IWebSocket + { + /// + /// The logger + /// + private readonly ILogger _logger; + + /// + /// Gets or sets the web socket. + /// + /// The web socket. + private WebSocket WebSocket { get; set; } + + /// + /// Initializes a new instance of the class. + /// + /// The socket. + /// The logger. + /// socket + public NativeWebSocket(WebSocket socket, ILogger logger) + { + if (socket == null) + { + throw new ArgumentNullException("socket"); + } + + if (logger == null) + { + throw new ArgumentNullException("logger"); + } + + _logger = logger; + WebSocket = socket; + + Receive(); + } + + /// + /// Gets or sets the state. + /// + /// The state. + public WebSocketState State + { + get { return WebSocket.State; } + } + + /// + /// Receives this instance. + /// + private async void Receive() + { + while (true) + { + byte[] bytes; + + try + { + bytes = await ReceiveBytesAsync(CancellationToken.None).ConfigureAwait(false); + } + catch (WebSocketException ex) + { + _logger.ErrorException("Error reveiving web socket message", ex); + + break; + } + + if (OnReceiveDelegate != null) + { + OnReceiveDelegate(bytes); + } + } + } + + /// + /// Receives the async. + /// + /// The cancellation token. + /// Task{WebSocketMessageInfo}. + /// Connection closed + private async Task ReceiveBytesAsync(CancellationToken cancellationToken) + { + var bytes = new byte[4096]; + var buffer = new ArraySegment(bytes); + + var result = await WebSocket.ReceiveAsync(buffer, cancellationToken).ConfigureAwait(false); + + if (result.CloseStatus.HasValue) + { + throw new WebSocketException("Connection closed"); + } + + return buffer.Array; + } + + /// + /// Sends the async. + /// + /// The bytes. + /// The type. + /// if set to true [end of message]. + /// The cancellation token. + /// Task. + public Task SendAsync(byte[] bytes, WebSocketMessageType type, bool endOfMessage, CancellationToken cancellationToken) + { + return WebSocket.SendAsync(new ArraySegment(bytes), type, true, cancellationToken); + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + } + + /// + /// Releases unmanaged and - optionally - managed resources. + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool dispose) + { + if (dispose) + { + WebSocket.Dispose(); + } + } + + /// + /// Gets or sets the receive action. + /// + /// The receive action. + public Action OnReceiveDelegate { get; set; } + } +} diff --git a/MediaBrowser.Networking/Web/ServerFactory.cs b/MediaBrowser.Networking/Web/ServerFactory.cs new file mode 100644 index 0000000000..b93f2ca1c8 --- /dev/null +++ b/MediaBrowser.Networking/Web/ServerFactory.cs @@ -0,0 +1,28 @@ +using MediaBrowser.Common.Kernel; +using MediaBrowser.Common.Net; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Serialization; + +namespace MediaBrowser.Networking.Web +{ + /// + /// Class ServerFactory + /// + public static class ServerFactory + { + /// + /// Creates the server. + /// + /// The application host. + /// The kernel. + /// The protobuf serializer. + /// The logger. + /// Name of the server. + /// The default redirectpath. + /// IHttpServer. + public static IHttpServer CreateServer(IApplicationHost applicationHost, IKernel kernel, IProtobufSerializer protobufSerializer, ILogger logger, string serverName, string defaultRedirectpath) + { + return new HttpServer(applicationHost, kernel, protobufSerializer, logger, serverName, defaultRedirectpath); + } + } +} diff --git a/MediaBrowser.Networking/WebSocket/AlchemyWebSocket.cs b/MediaBrowser.Networking/WebSocket/AlchemyWebSocket.cs index fbdb3186f6..5eca1a78c5 100644 --- a/MediaBrowser.Networking/WebSocket/AlchemyWebSocket.cs +++ b/MediaBrowser.Networking/WebSocket/AlchemyWebSocket.cs @@ -1,9 +1,9 @@ using Alchemy.Classes; using MediaBrowser.Common.Net; -using MediaBrowser.Common.Serialization; using MediaBrowser.Model.Logging; using System; using System.Net.WebSockets; +using System.Text; using System.Threading; using System.Threading.Tasks; @@ -83,9 +83,9 @@ namespace MediaBrowser.Networking.WebSocket { try { - var messageResult = JsonSerializer.DeserializeFromString(json); + var bytes = Encoding.UTF8.GetBytes(json); - OnReceiveDelegate(messageResult); + OnReceiveDelegate(bytes); } catch (Exception ex) { @@ -128,6 +128,6 @@ namespace MediaBrowser.Networking.WebSocket /// Gets or sets the receive action. /// /// The receive action. - public Action OnReceiveDelegate { get; set; } + public Action OnReceiveDelegate { get; set; } } } -- cgit v1.2.3