using System; using System.Net.WebSockets; using System.Text; using System.Threading; using System.Threading.Tasks; using Emby.Server.Implementations.Net; using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.SocketSharp { public class SharpWebSocket : IWebSocket { /// /// The logger /// private readonly ILogger _logger; public event EventHandler Closed; /// /// Gets or sets the web socket. /// /// The web socket. private readonly WebSocket _webSocket; private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); private bool _disposed; public SharpWebSocket(WebSocket socket, ILogger logger) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _webSocket = socket ?? throw new ArgumentNullException(nameof(socket)); } /// /// Gets the state. /// /// The state. public WebSocketState State => _webSocket.State; /// /// Sends the async. /// /// The bytes. /// if set to true [end of message]. /// The cancellation token. /// Task. public Task SendAsync(byte[] bytes, bool endOfMessage, CancellationToken cancellationToken) { return _webSocket.SendAsync(new ArraySegment(bytes), WebSocketMessageType.Binary, endOfMessage, cancellationToken); } /// /// Sends the asynchronous. /// /// The text. /// if set to true [end of message]. /// The cancellation token. /// Task. public Task SendAsync(string text, bool endOfMessage, CancellationToken cancellationToken) { return _webSocket.SendAsync(new ArraySegment(Encoding.UTF8.GetBytes(text)), WebSocketMessageType.Text, endOfMessage, cancellationToken); } /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// /// 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 (_disposed) { return; } if (dispose) { _cancellationTokenSource.Cancel(); if (_webSocket.State == WebSocketState.Open) { _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closed by client", CancellationToken.None); } Closed?.Invoke(this, EventArgs.Empty); } _disposed = true; } /// /// Gets or sets the receive action. /// /// The receive action. public Action OnReceiveBytes { get; set; } } }