internal CompressionWebSocket(Stream stream, string subprotocol, TimeSpan keepAliveInterval, int receiveBufferSize) { _stream = stream; _subprotocol = subprotocol; _receiveBuffer = new byte[Math.Max(receiveBufferSize, MAX_MESSAGE_HEADER_LENGTH)]; _abortSource.Token.Register(source => { CompressionWebSocket webSocket = (CompressionWebSocket)source; lock (webSocket.StateUpdateLock) { WebSocketState state = webSocket._state; if (state != WebSocketState.Closed && state != WebSocketState.Aborted) { webSocket._state = ((state != WebSocketState.None) && (state != WebSocketState.Connecting)) ? WebSocketState.Aborted : WebSocketState.Closed; } } }, this); if (keepAliveInterval > TimeSpan.Zero) { _keepAliveTimer = new Timer(source => ((CompressionWebSocket)source).SendKeepAliveFrameAsync(), this, keepAliveInterval, keepAliveInterval); } }
private Task SendFrameLockAcquiredNonCancelableAsync(WebSocketMessageOpcode opcode, bool compressed, bool endOfMessage, ArraySegment <byte> payloadBuffer) { Task writeTask = null; bool releaseSemaphore = true; try { int sendBytes = WriteFrameToSendBuffer(opcode, compressed, endOfMessage, payloadBuffer); writeTask = _stream.WriteAsync(_sendBuffer, 0, sendBytes, CancellationToken.None); if (writeTask.IsCompleted) { writeTask.GetAwaiter().GetResult(); return(TargetFrameworksHelper.CompletedTask); } releaseSemaphore = false; } catch (Exception ex) { return(TargetFrameworksHelper.FromException(_state == WebSocketState.Aborted ? CreateOperationCanceledException(ex) : new WebSocketException(WebSocketError.ConnectionClosedPrematurely, ex))); } finally { if (releaseSemaphore) { _sendFrameAsyncLock.Release(); } } return(writeTask.ContinueWith((task, source) => { CompressionWebSocket webSocket = (CompressionWebSocket)source; webSocket._sendFrameAsyncLock.Release(); try { task.GetAwaiter().GetResult(); } catch (Exception ex) { throw webSocket._state == WebSocketState.Aborted ? CreateOperationCanceledException(ex) : new WebSocketException(WebSocketError.ConnectionClosedPrematurely, ex); } }, this, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default)); }