public void CloseFrameReceivedInUnexpectedState(Guid guid, WebSocketState webSocketState, WebSocketCloseStatus?closeStatus, string statusDescription) { if (this.IsEnabled()) { string closeStatusDesc = $"{closeStatus}"; WriteEvent(34, guid, webSocketState, closeStatusDesc, statusDescription ?? string.Empty); } }
public WebSocketClosedEventArgs(WebSocketCloseStatus?status, string description, Exception exception) { Status = status; Description = description; Exception = exception; }
/// <summary> /// Fires with the connection with the client has closed and after OnClose /// </summary> public virtual Task OnCloseAsync(WebSocketCloseStatus?closeStatus, string closeStatusDescription) { return(Task.Delay(0)); }
public WebSocketStringResult(int count, WebSocketMessageType messageType, bool endOfMessage, WebSocketCloseStatus?closeStatus, string closeStatusDescription) : base(count, messageType, endOfMessage, closeStatus, closeStatusDescription) { }
public CloseMessage(WebSocketCloseStatus?closeStatus, string closeStatusDescription) { CloseStatus = closeStatus; CloseStatusDescription = closeStatusDescription; }
/// <summary>Processes a received close message.</summary> /// <param name="header">The message header.</param> /// <param name="cancellationToken">The cancellation token to use to cancel the websocket.</param> /// <returns>The received result message.</returns> private async Task<WebSocketReceiveResult> HandleReceivedCloseAsync( MessageHeader header, CancellationToken cancellationToken) { lock (StateUpdateLock) { _receivedCloseFrame = true; if (_state < WebSocketState.CloseReceived) { _state = WebSocketState.CloseReceived; } } WebSocketCloseStatus closeStatus = WebSocketCloseStatus.NormalClosure; string closeStatusDescription = string.Empty; // Handle any payload by parsing it into the close status and description. if (header.PayloadLength == 1) { // The close payload length can be 0 or >= 2, but not 1. await CloseWithReceiveErrorAndThrowAsync(WebSocketCloseStatus.ProtocolError, WebSocketError.Faulted, cancellationToken).ConfigureAwait(false); } else if (header.PayloadLength >= 2) { if (_receiveBufferCount < header.PayloadLength) { await EnsureBufferContainsAsync((int)header.PayloadLength, cancellationToken).ConfigureAwait(false); } if (_isServer) { ApplyMask(_receiveBuffer, _receiveBufferOffset, header.Mask, 0, header.PayloadLength); } closeStatus = (WebSocketCloseStatus)(_receiveBuffer[_receiveBufferOffset] << 8 | _receiveBuffer[_receiveBufferOffset + 1]); if (!IsValidCloseStatus(closeStatus)) { await CloseWithReceiveErrorAndThrowAsync(WebSocketCloseStatus.ProtocolError, WebSocketError.Faulted, cancellationToken).ConfigureAwait(false); } if (header.PayloadLength > 2) { try { closeStatusDescription = s_textEncoding.GetString(_receiveBuffer, _receiveBufferOffset + 2, (int)header.PayloadLength - 2); } catch (DecoderFallbackException exc) { await CloseWithReceiveErrorAndThrowAsync(WebSocketCloseStatus.ProtocolError, WebSocketError.Faulted, cancellationToken, exc).ConfigureAwait(false); } } ConsumeFromBuffer((int)header.PayloadLength); } // Store the close status and description onto the instance. _closeStatus = closeStatus; _closeStatusDescription = closeStatusDescription; // And return them as part of the result message. return new WebSocketReceiveResult(0, WebSocketMessageType.Close, true, closeStatus, closeStatusDescription); }
public WebSocketMessage(WebSocketCloseStatus?status, string closeStatDesc) { WebSocketCloseStatus = status; CloseStatDesc = closeStatDesc; }
public WebSocketReceivedResultEventArgs(WebSocketCloseStatus?closeStatus, string closeStatDesc) { this.CloseStatus = closeStatus; this.CloseStatDescription = closeStatDesc; }
private void InvokeOnMessage(OpCode opCode, WebSocketCloseStatus?status, ArraySegment <byte> buffer) => OnMessage?.Invoke(opCode, status, buffer);
public override Task OnCloseAsync(WebSocketCloseStatus?closeStatus, string closeStatusDescription) { return(_connection.OnCloseAsync?.Invoke() ?? Task.FromResult(true)); }
public override Task OnCloseAsync(WebSocketCloseStatus?closeStatus, string closeStatusDescription) { Server.Stop(); return(base.OnCloseAsync(closeStatus, closeStatusDescription)); }
public override void OnClose(WebSocketCloseStatus?closeStatus, string closeStatusDescription) { logger.Info("ContainerProcessHandler.OnClose", new Dictionary <string, object> { { "closeStatus", closeStatus.ToString() }, { "closeStatusDescription", closeStatusDescription } }); }
public WebSocketClosedException(string message, Exception innerException, WebSocketCloseStatus?closeStatus = null) : base(message, innerException) { CloseStatus = closeStatus; }
public static WebSocketMessage Close(WebSocketCloseStatus?status) => new WebSocketMessage { Type = InternalWebsocketMessageType.Close, CloseStatus = status };
public static void ClientClosed(ILogger logger, WebSocketCloseStatus?closeStatus, string closeDescription) { _clientClosed(logger, closeStatus, closeDescription, null); }
protected override void DisconnectOccurred(WebSocketCloseStatus?result) { this.Connected = this.Authenticated = false; base.DisconnectOccurred(result); }
public override async Task CloseAsync(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); bool callClose = false; lock (_stateLock) { callClose = (_state != WebSocketState.CloseSent) && (_state != WebSocketState.Closed); } InterlockedCheckAndUpdateCloseState(WebSocketState.CloseSent, s_validCloseStates); using (CancellationTokenRegistration ctr = ThrowOrRegisterCancellation(cancellationToken)) { if (callClose) { _messageWebSocket.Close((ushort) closeStatus, statusDescription ?? String.Empty); } var result = await _closeWebSocketReceiveResultTcs.Task; _closeStatus = result.CloseStatus; _closeStatusDescription = result.CloseStatusDescription; InterlockedCheckAndUpdateCloseState(WebSocketState.CloseReceived, s_validCloseStates); } }
public override async Task<WebSocketReceiveResult> ReceiveAsync(ArraySegment<byte> buffer, CancellationToken cancellationToken) { ThrowIfDisposed(); ThrowIfInputClosed(); ValidateSegment(buffer); var result = await _session.ReceiveAsync(buffer, cancellationToken); if (result.MessageType == WebSocketMessageType.Close) { _closeStatusDescription = result.CloseStatusDescription; _closeStatus = result.CloseStatus; if (State == WebSocketState.Open) { _state = WebSocketState.CloseReceived; } else if (State == WebSocketState.CloseSent) { _state = WebSocketState.Closed; _session.WebSocketDispose(); } } return result; }
internal static CloseReason FromCloseFrame(WebSocketCloseStatus?closeStatus, string?closeDescription, string?additionalDescription, ShutdownRequest?shutdownRequest) { return(new CloseReason(null, closeStatus, closeDescription, additionalDescription, shutdownRequest)); }
public override void OnClose(WebSocketCloseStatus?closeStatus, string closeStatusDescription) { logger.Info("OnClose: {0} :: {1}", closeStatus.ToString(), closeStatusDescription); }
// 연결이 끊어진 경우 retry 여부 private void OnDisconnected(WebSocketCloseStatus?status) { Log.Debug("connection lost!"); }
public WebSocketReceiveResult(int count, WebSocketMessageType messageType, bool endOfMessage, WebSocketCloseStatus?closeStatus, string closeStatusDescription) { if (count < 0) { throw new ArgumentOutOfRangeException("count"); } this.Count = count; this.EndOfMessage = endOfMessage; this.MessageType = messageType; this.CloseStatus = closeStatus; this.CloseStatusDescription = closeStatusDescription; }
private async Task ConnectAsyncJavaScript(Uri uri, CancellationToken cancellationToken) { var tcsConnect = new TaskCompletionSource <bool> (); // For Abort/Dispose. Calling Abort on the request at any point will close the connection. cts.Token.Register(AbortRequest); // Wrap the cancellationToken in a using so that it can be disposed of whether // we successfully connected or failed trying. // Otherwise any timeout/cancellation would apply to the full session. // In the failure case we need to release the references and dispose of the objects. using (cancellationToken.Register(() => tcsConnect.TrySetCanceled())) { try { Core.Array subProtocols = null; if (Options.RequestedSubProtocols.Count > 0) { subProtocols = new Core.Array(); foreach (var item in Options.RequestedSubProtocols) { subProtocols.Push(item); } } innerWebSocket = new HostObject("WebSocket", uri.ToString(), subProtocols); subProtocols?.Dispose(); // Setup the onError callback onError = new Action <JSObject> ((errorEvt) => { errorEvt.Dispose(); }); // Attach the onError callback innerWebSocket.SetObjectProperty("onerror", onError); // Setup the onClose callback onClose = new Action <JSObject> ((closeEvt) => { innerWebSocketCloseStatus = (WebSocketCloseStatus)closeEvt.GetObjectProperty("code"); innerWebSocketCloseStatusDescription = closeEvt.GetObjectProperty("reason")?.ToString(); var mess = new ReceivePayload(WebSocketHelpers.EmptyPayload, WebSocketMessageType.Close); receiveMessageQueue.BufferPayload(mess); if (!tcsConnect.Task.IsCanceled && !tcsConnect.Task.IsCompleted && !tcsConnect.Task.IsFaulted) { tcsConnect.SetException(new WebSocketException(WebSocketError.NativeError)); } else { tcsClose?.SetResult(true); } closeEvt.Dispose(); }); // Attach the onClose callback innerWebSocket.SetObjectProperty("onclose", onClose); // Setup the onOpen callback onOpen = new Action <JSObject> ((evt) => { if (!cancellationToken.IsCancellationRequested) { // Change internal state to 'connected' to enable the other methods if (Interlocked.CompareExchange(ref state, connected, connecting) != connecting) { // Aborted/Disposed during connect. throw new ObjectDisposedException(GetType().FullName); } tcsConnect.SetResult(true); } evt.Dispose(); }); // Attach the onOpen callback innerWebSocket.SetObjectProperty("onopen", onOpen); // Setup the onMessage callback onMessage = new Action <JSObject> ((messageEvent) => { ThrowIfNotConnected(); // get the events "data" var eventData = messageEvent.GetObjectProperty("data"); // If the messageEvent's data property is marshalled as a JSObject then we are dealing with // binary data if (eventData is JSObject) { // TODO: Handle ArrayBuffer binary type but have only seen 'blob' so far without // changing the default websocket binary type manually. if (innerWebSocket.GetObjectProperty("binaryType").ToString() == "blob") { Action <JSObject> loadend = null; // Create a new "FileReader" object using (var reader = new HostObject("FileReader")) { loadend = new Action <JSObject> ((loadEvent) => { using (var target = (JSObject)loadEvent.GetObjectProperty("target")) { if ((int)target.GetObjectProperty("readyState") == 2) { using (var binResult = (ArrayBuffer)target.GetObjectProperty("result")) { var mess = new ReceivePayload(binResult, WebSocketMessageType.Binary); receiveMessageQueue.BufferPayload(mess); Runtime.FreeObject(loadend); } } } loadEvent.Dispose(); }); reader.Invoke("addEventListener", "loadend", loadend); using (var blobData = (JSObject)messageEvent.GetObjectProperty("data")) reader.Invoke("readAsArrayBuffer", blobData); } } else { throw new NotImplementedException($"WebSocket bynary type '{innerWebSocket.GetObjectProperty ("binaryType").ToString ()}' not supported."); } } else if (eventData is string) { var mess = new ReceivePayload(Encoding.UTF8.GetBytes(((string)eventData).ToString()), WebSocketMessageType.Text); receiveMessageQueue.BufferPayload(mess); } messageEvent.Dispose(); }); // Attach the onMessage callaback innerWebSocket.SetObjectProperty("onmessage", onMessage); await tcsConnect.Task; } catch (Exception wse) { ConnectExceptionCleanup(); WebSocketException wex = new WebSocketException("WebSocket connection failure.", wse); throw wex; } } }
private async Task<WebSocketReceiveResult> ProcessCloseFrameAsync(CancellationToken cancellationToken) { // The close message should be less than 125 bytes and fit in the buffer. await EnsureDataAvailableOrReadAsync((int)_frameBytesRemaining, CancellationToken.None); // Status code and message are optional if (_frameBytesRemaining >= 2) { if (_unmaskInput) { Utilities.MaskInPlace(_frameInProgress.MaskKey, new ArraySegment<byte>(_receiveBuffer, _receiveBufferOffset, (int)_frameBytesRemaining)); } _closeStatus = (WebSocketCloseStatus)((_receiveBuffer[_receiveBufferOffset] << 8) | _receiveBuffer[_receiveBufferOffset + 1]); _closeStatusDescription = Encoding.UTF8.GetString(_receiveBuffer, _receiveBufferOffset + 2, (int)_frameBytesRemaining - 2) ?? string.Empty; } else { _closeStatus = _closeStatus ?? WebSocketCloseStatus.NormalClosure; _closeStatusDescription = _closeStatusDescription ?? string.Empty; } Contract.Assert(_frameInProgress.Fin); WebSocketReceiveResult result = new WebSocketReceiveResult(0, WebSocketMessageType.Close, _frameInProgress.Fin, _closeStatus.Value, _closeStatusDescription); if (State == WebSocketState.Open) { _state = WebSocketState.CloseReceived; } else if (State == WebSocketState.CloseSent) { _state = WebSocketState.Closed; _stream.Dispose(); } return result; }
public extern WebSocketReceiveResult(int count, WebSocketMessageType messageType, bool endOfMessage, WebSocketCloseStatus?closeStatus, string closeStatusDescription);
public override void OnClose(WebSocketCloseStatus?closeStatus, string closeStatusDescription) { DisconnectFromChatSession(sessionId); }
/// <summary> /// Fires with the connection with the client has closed /// </summary> public virtual void OnClose(WebSocketCloseStatus?closeStatus, string closeStatusDescription) { }
public static partial void ClientClosed(ILogger logger, WebSocketCloseStatus?status, string description);
public ValueWebSocketReceiveResult GetResult(int count, WebSocketMessageType messageType, bool endOfMessage, WebSocketCloseStatus?closeStatus, string closeDescription) => new ValueWebSocketReceiveResult(count, messageType, endOfMessage); // closeStatus/closeDescription are ignored
public override void OnClose(WebSocketCloseStatus?closeStatus, string closeStatusDescription) { OnCloseCalled = true; CloseStatus = closeStatus; CloseDescription = closeStatusDescription; }
public static void WebSocketClosed(ILogger logger, WebSocketCloseStatus?closeStatus) { _webSocketClosed(logger, closeStatus, null); }
private async Task<WebSocketReceiveResult> ProcessCloseFrameAsync(CancellationToken cancellationToken) { // The close message should be less than 125 bytes and fit in the buffer. await EnsureDataAvailableOrReadAsync((int)_frameBytesRemaining, CancellationToken.None); // Status code and message are optional if (_frameBytesRemaining >= 2) { if (_unmaskInput) { Utilities.MaskInPlace(_frameInProgress.MaskKey, new ArraySegment<byte>(_receiveBuffer, _receiveBufferOffset, (int)_frameBytesRemaining)); } _closeStatus = (WebSocketCloseStatus)((_receiveBuffer[_receiveBufferOffset] << 8) | _receiveBuffer[_receiveBufferOffset + 1]); if (!ValidateCloseStatus(_closeStatus.Value)) { await SendErrorAbortAndThrow(WebSocketCloseStatus.ProtocolError, "Invalid close status code.", cancellationToken); } try { var encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true); _closeStatusDescription = encoding.GetString(_receiveBuffer, _receiveBufferOffset + 2, (int)_frameBytesRemaining - 2) ?? string.Empty; } catch (DecoderFallbackException) { await SendErrorAbortAndThrow(WebSocketCloseStatus.ProtocolError, "Invalid UTF-8 close message.", cancellationToken); } } else if (_frameBytesRemaining == 1) { await SendErrorAbortAndThrow(WebSocketCloseStatus.ProtocolError, "Invalid close body.", cancellationToken); } else { _closeStatus = _closeStatus ?? WebSocketCloseStatus.NormalClosure; _closeStatusDescription = _closeStatusDescription ?? string.Empty; } Contract.Assert(_frameInProgress.Fin); WebSocketReceiveResult result = new WebSocketReceiveResult(0, WebSocketMessageType.Close, _frameInProgress.Fin, _closeStatus.Value, _closeStatusDescription); if (State == WebSocketState.Open) { _state = WebSocketState.CloseReceived; } else if (State == WebSocketState.CloseSent) { _state = WebSocketState.Closed; _stream.Dispose(); } return result; }
public override async Task<WebSocketReceiveResult> ReceiveAsync(ArraySegment<byte> buffer, CancellationToken cancellationToken) { ThrowIfDisposed(); ThrowIfInputClosed(); ValidateSegment(buffer); // TODO: InvalidOperationException if any receives are currently in progress. Message receiveMessage = _receiveMessage; _receiveMessage = null; if (receiveMessage == null) { receiveMessage = await _receiveBuffer.ReceiveAsync(cancellationToken); } if (receiveMessage.MessageType == WebSocketMessageType.Close) { _closeStatus = receiveMessage.CloseStatus; _closeStatusDescription = receiveMessage.CloseStatusDescription ?? string.Empty; var result = new WebSocketReceiveResult(0, WebSocketMessageType.Close, true, _closeStatus, _closeStatusDescription); if (_state == WebSocketState.Open) { _state = WebSocketState.CloseReceived; } else if (_state == WebSocketState.CloseSent) { _state = WebSocketState.Closed; Close(); } return result; } else { int count = Math.Min(buffer.Count, receiveMessage.Buffer.Count); bool endOfMessage = count == receiveMessage.Buffer.Count; Array.Copy(receiveMessage.Buffer.Array, receiveMessage.Buffer.Offset, buffer.Array, buffer.Offset, count); if (!endOfMessage) { receiveMessage.Buffer = new ArraySegment<byte>(receiveMessage.Buffer.Array, receiveMessage.Buffer.Offset + count, receiveMessage.Buffer.Count - count); _receiveMessage = receiveMessage; } endOfMessage = endOfMessage && receiveMessage.EndOfMessage; return new WebSocketReceiveResult(count, receiveMessage.MessageType, endOfMessage); } }
public void ConstructorTest_Success(int count, WebSocketMessageType messageType, bool endOfMessage, WebSocketCloseStatus?closeStatus, string closeStatusDescription) { var wsrr = new WebSocketReceiveResult(count, messageType, endOfMessage, closeStatus, closeStatusDescription); Assert.Equal(wsrr.Count, count); Assert.Equal(wsrr.MessageType, messageType); Assert.Equal(wsrr.EndOfMessage, endOfMessage); Assert.Equal(wsrr.CloseStatus, closeStatus); Assert.Equal(wsrr.CloseStatusDescription, closeStatusDescription); }
public override async Task<WebSocketReceiveResult> ReceiveAsync(ArraySegment<byte> buffer, CancellationToken cancellationToken) { InterlockedCheckValidStates(s_validReceiveStates); using (CancellationTokenRegistration ctr = ThrowOrRegisterCancellation(cancellationToken)) { _webSocketReceiveResultTcs = new TaskCompletionSource<WebSocketReceiveResult>(); _receiveAsyncBufferTcs.TrySetResult(buffer); Task<WebSocketReceiveResult> completedTask = await Task.WhenAny( _webSocketReceiveResultTcs.Task, _closeWebSocketReceiveResultTcs.Task); WebSocketReceiveResult result = await completedTask; if (result.MessageType == WebSocketMessageType.Close) { _closeStatus = result.CloseStatus; _closeStatusDescription = result.CloseStatusDescription; InterlockedCheckAndUpdateCloseState(WebSocketState.CloseReceived, s_validCloseOutputStates); } else { _webSocketReceiveResultTcs = new TaskCompletionSource<WebSocketReceiveResult>(); } InterlockedCheckValidStates(s_validAfterReceiveStates); return result; } }
public WebSocketClosedEventArgs(string clientid, WebSocketCloseStatus?res, string closeStatDesc) : base(res, closeStatDesc) { ClientId = clientid; }
private void UpdateServerCloseStatus() { uint ret; ushort serverStatus; var closeDescription = new byte[WebSocketValidate.MaxControlFramePayloadLength]; uint closeDescriptionConsumed; lock (_operation.Lock) { ret = Interop.WinHttp.WinHttpWebSocketQueryCloseStatus( _operation.WebSocketHandle, out serverStatus, closeDescription, (uint)closeDescription.Length, out closeDescriptionConsumed); if (ret != Interop.WinHttp.ERROR_SUCCESS) { throw WinHttpException.CreateExceptionUsingError((int)ret); } _closeStatus = (WebSocketCloseStatus)serverStatus; _closeStatusDescription = Encoding.UTF8.GetString(closeDescription, 0, (int)closeDescriptionConsumed); } }
public override async Task <WebSocketReceiveResult> ReceiveAsync(ArraySegment <byte> buffer, CancellationToken cancellationToken) { try { while (_internalBuffer.Buffer == null || _internalBuffer.Buffer.Length == 0) { await _input.WaitToReadAsync(cancellationToken).ConfigureAwait(false); if (_input.TryRead(out var message)) { if (message.MessageType == WebSocketMessageType.Close) { _state = WebSocketState.CloseReceived; _closeStatus = message.CloseStatus; _closeStatusDescription = message.CloseStatusDescription; return(new WebSocketReceiveResult(0, WebSocketMessageType.Close, true, message.CloseStatus, message.CloseStatusDescription)); } _internalBuffer = message; } else { await Task.Delay(100).ConfigureAwait(false); } } var length = _internalBuffer.Buffer.Length; if (buffer.Count < _internalBuffer.Buffer.Length) { length = Math.Min(buffer.Count, _internalBuffer.Buffer.Length); Buffer.BlockCopy(_internalBuffer.Buffer, 0, buffer.Array, buffer.Offset, length); } else { Buffer.BlockCopy(_internalBuffer.Buffer, 0, buffer.Array, buffer.Offset, length); } var endOfMessage = _internalBuffer.EndOfMessage; if (length > 0) { // Remove the sent bytes from the remaining buffer _internalBuffer.Buffer = _internalBuffer.Buffer.AsMemory().Slice(length).ToArray(); endOfMessage = _internalBuffer.Buffer.Length == 0 && endOfMessage; } return(new WebSocketReceiveResult(length, _internalBuffer.MessageType, endOfMessage)); } catch (WebSocketException ex) { switch (ex.WebSocketErrorCode) { case WebSocketError.ConnectionClosedPrematurely: _state = WebSocketState.Aborted; break; } // Complete the client side if there's an error _output.TryComplete(); throw; } throw new InvalidOperationException("Unexpected close"); }