/// <summary> /// Closes the WebSocket connection using the close handshake defined in the /// WebSocket protocol specification section 7. /// </summary> /// <param name="closeStatus">Indicates the reason for closing the WebSocket connection.</param> /// <param name="statusDescription">Specifies a human readable explanation as to why the connection is closed.</param> /// <param name="cancellationToken">The token that can be used to propagate notification that operations should be canceled.</param> /// <returns>Returns System.Threading.Tasks.Task.</returns> public Task CloseAsync(CloseCodeStatus closeStatus, string statusDescription, CancellationToken cancellationToken) { // Create a new task. return(Task.Factory.StartNew(() => { try { // Check can be closed. var msg = _readyState.CheckIfClosable() ?? closeStatus.CheckIfValidCloseParameters(statusDescription); if (!String.IsNullOrEmpty(msg)) { return; } // If cancellation has not been requested. if (!cancellationToken.IsCancellationRequested) { // If no status code. if (closeStatus.IsNoStatusCode()) { // Close the connection. Close(new CloseEventArgs(), true, true); return; } // Close the connection. var send = !closeStatus.IsReserved(); Close(new CloseEventArgs(closeStatus, statusDescription), send, send); } } catch { } }, cancellationToken)); }
/// <summary> /// Is reserved. /// </summary> /// <param name="code">The CloseCodeStatus code.</param> /// <returns>True if reserved.</returns> public static bool IsReserved(this CloseCodeStatus code) { return(code == CloseCodeStatus.Undefined || code == CloseCodeStatus.NoStatusReceived || code == CloseCodeStatus.AbnormalClosure || code == CloseCodeStatus.TLSHandshake); }
/// <summary> /// Check if valid close parameters. /// </summary> /// <param name="code">The code.</param> /// <param name="reason">The reason.</param> /// <returns>The message.</returns> public static string CheckIfValidCloseParameters(this CloseCodeStatus code, string reason) { return(code.IsNoStatusCode() && !reason.IsNullOrEmpty() ? "NoStatusCode cannot have a reason." : !reason.IsNullOrEmpty() && Encoding.UTF8.GetBytes(reason).Length > 123 ? "A reason has greater than the allowable max size." : null); }
/// <summary> /// Get a close code status messsage. /// </summary> /// <param name="code">Close code status.</param> /// <returns>The message.</returns> public static string GetMessage(this CloseCodeStatus code) { return(code == CloseCodeStatus.ProtocolError ? "A WebSocket protocol error has occurred." : code == CloseCodeStatus.UnsupportedData ? "An incorrect data has been received." : code == CloseCodeStatus.AbnormalClosure ? "An exception has occurred." : code == CloseCodeStatus.InvalidFramePayloadData ? "An inconsistent data has been received." : code == CloseCodeStatus.PolicyViolation ? "A policy violation has occurred." : code == CloseCodeStatus.MessageTooBig ? "A too big data has been received." : code == CloseCodeStatus.MandatoryExtension ? "WebSocket client didn't receive expected extension(s)." : code == CloseCodeStatus.InternalServerError ? "WebSocket server got an internal error." : code == CloseCodeStatus.TLSHandshake ? "An error has occurred while handshaking." : String.Empty); }
/// <summary> /// Close connection. /// </summary> /// <param name="code">The close code.</param> /// <param name="reason">The message.</param> internal CloseEventArgs(CloseCodeStatus code, string reason) : this((ushort)code, reason) { }
/// <summary> /// Close connection. /// </summary> /// <param name="code">The close code.</param> internal CloseEventArgs(CloseCodeStatus code) : this((ushort)code) { }
/// <summary> /// Process unsupported frame. /// </summary> /// <param name="frame">The frame.</param> /// <param name="code">The close code.</param> /// <param name="reason">The invalid description.</param> /// <returns>Returns false.</returns> private bool ProcessUnsupportedFrame(Frame frame, CloseCodeStatus code, string reason) { ProcessException(new WebSocketException(code, reason), null); return(false); }
/// <summary> /// Is no status received. /// </summary> /// <param name="code">The code.</param> /// <returns>True if no status; else false.</returns> public static bool IsNoStatusCode(this CloseCodeStatus code) { return(code == CloseCodeStatus.NoStatusReceived); }
/// <summary> /// The exception that is thrown when a <see cref="WebSocket"/> gets a fatal error. /// </summary> /// <param name="code">The close code status.</param> public WebSocketException(CloseCodeStatus code) : this(code, null, null) { }
/// <summary> /// The exception that is thrown when a <see cref="WebSocket"/> gets a fatal error. /// </summary> /// <param name="code">The close code status.</param> /// <param name="message">The message.</param> /// <param name="innerException">Inner exception.</param> public WebSocketException(CloseCodeStatus code, string message, Exception innerException) : base(message ?? code.GetMessage(), innerException) { _code = code; }
/// <summary> /// The exception that is thrown when a <see cref="WebSocket"/> gets a fatal error. /// </summary> /// <param name="code">The close code status.</param> /// <param name="message">The message.</param> public WebSocketException(CloseCodeStatus code, string message) : this(code, message, null) { }
/// <summary> /// The exception that is thrown when a <see cref="WebSocket"/> gets a fatal error. /// </summary> /// <param name="code">The close code status.</param> /// <param name="innerException">Inner exception.</param> public WebSocketException(CloseCodeStatus code, Exception innerException) : this(code, null, innerException) { }