< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Channels.WebSocketTransportDuplexSessionChannel
Assembly: CoreWCF.Http
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Http/src/CoreWCF/Channels/WebSocketTransportDuplexSessionChannel.cs
Line coverage
69%
Covered lines: 303
Uncovered lines: 136
Coverable lines: 439
Total lines: 1210
Line coverage: 69%
Branch coverage
58%
Covered branches: 95
Total branches: 162
Branch coverage: 58.6%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)100%11100%
OnAbort()100%110%
GetProperty()50%2266.66%
CompleteCloseAsync()0%2242.85%
CloseOutputSessionCoreAsync()0%2242.85%
OnCloseAsync()100%11100%
ReturnConnectionIfNecessary(...)100%11100%
CloseOutputAsync(...)100%1176.92%
OnSendCoreAsync()33.33%6664%
EncodeMessage(...)100%11100%
Cleanup()100%22100%
OnCleanup()100%44100%
ThrowOnPendingException(...)50%2260%
CloseInternalAsync(...)33.33%6642.85%
CloseOutputImplAsync(...)37.5%8855.55%
GetWebSocketMessageType(...)50%2275%
.cctor()100%110%
.ctor(...)100%110%
.ctor(...)100%110%
.ctor(...)75%88100%
Initialize(...)100%11100%
OnAsyncReceiveCancelled(...)100%110%
AsyncReceiveCancelled()0%220%
ReceiveAsync()83.33%6690%
UpdateOpenNotificationMessageProperties(...)100%11100%
ReadBufferedMessageAsync()65%202065.9%
WaitForMessageAsync()100%110%
FinishUsingMessageStream(...)50%4475%
CheckCloseStatus(...)100%22100%
StartNextReceiveAsync()75%161675.67%
AddMessageProperties(...)75%4490.9%
GetPendingMessage()100%22100%
PrepareMessageAsync()68.75%161689.65%
.ctor(...)100%11100%
.ctor(...)100%11100%
Close()100%11100%
Flush()100%11100%
BeginRead(...)100%110%
EndRead(...)100%110%
Read(...)100%110%
ReadAsync()75%121280%
Seek(...)100%110%
SetLength(...)100%110%
Write(...)100%110%
WriteAsync()25%4454.54%
BeginWrite(...)100%110%
EndWrite(...)100%110%
WriteEndOfMessageAsync()50%4450%
CheckResultAndEnsureNotCloseMessage(...)50%2275%
GetBytesFromInitialReadBuffer(...)100%22100%
CleanupAsync()36.36%222237.5%
SetOutputCloseStatus(...)100%110%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Http/src/CoreWCF/Channels/WebSocketTransportDuplexSessionChannel.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System;
 5using System.Collections.Generic;
 6using System.Collections.ObjectModel;
 7using System.Diagnostics;
 8using System.IO;
 9using System.Net.WebSockets;
 10using System.Security.Principal;
 11using System.Threading;
 12using System.Threading.Tasks;
 13using CoreWCF.Runtime;
 14using CoreWCF.Security;
 15using Microsoft.AspNetCore.Http;
 16
 17namespace CoreWCF.Channels
 18{
 19    internal abstract class WebSocketTransportDuplexSessionChannel : TransportDuplexSessionChannel
 20    {
 21        private WebSocket _webSocket = null;
 22        private int _cleanupStatus = WebSocketHelper.OperationNotStarted;
 1123        private readonly WebSocketCloseDetails _webSocketCloseDetails = new WebSocketCloseDetails();
 1124        private bool _shouldDisposeWebSocketAfterClosed = true;
 25
 26        public WebSocketTransportDuplexSessionChannel(IHttpTransportFactorySettings settings, EndpointAddress localAddre
 1127            : base(settings, localAddress, localVia, EndpointAddress.AnonymousAddress, settings.MessageVersion.Addressin
 28        {
 29            Fx.Assert(settings.WebSocketSettings != null, "IHttpTransportFactorySettings.WebSocketTransportSettings shou
 1130            WebSocketSettings = settings.WebSocketSettings;
 1131            TransferMode = settings.TransferMode;
 1132            MaxBufferSize = settings.MaxBufferSize;
 1133            TransportFactorySettings = settings;
 1134        }
 35
 36        protected WebSocket WebSocket
 37        {
 38            get
 39            {
 7040                return _webSocket;
 41            }
 42
 43            set
 44            {
 45                Fx.Assert(value != null, "value should not be null.");
 46                Fx.Assert(_webSocket == null, "webSocket should not be set before this set call.");
 1147                _webSocket = value;
 1148            }
 49        }
 50
 1151        protected WebSocketTransportSettings WebSocketSettings { get; }
 52
 2653        protected TransferMode TransferMode { get; }
 54
 1155        protected int MaxBufferSize { get; }
 56
 1157        protected ITransportFactorySettings TransportFactorySettings { get; }
 58
 59        protected bool ShouldDisposeWebSocketAfterClosed
 60        {
 61            set
 62            {
 1163                _shouldDisposeWebSocketAfterClosed = value;
 1164            }
 65        }
 66
 67        protected override void OnAbort()
 68        {
 69            //if (TD.WebSocketConnectionAbortedIsEnabled())
 70            //{
 71            //    TD.WebSocketConnectionAborted(
 72            //        this.EventTraceActivity,
 73            //        this.WebSocket != null ? this.WebSocket.GetHashCode() : -1);
 74            //}
 75
 076            Cleanup();
 077        }
 78
 79        public override T GetProperty<T>()
 80        {
 1281            if (typeof(T) == typeof(IWebSocketCloseDetails))
 82            {
 083                return _webSocketCloseDetails as T;
 84            }
 85
 1286            return base.GetProperty<T>();
 87        }
 88
 89        protected override async Task CompleteCloseAsync(CancellationToken token)
 90        {
 91            //if (TD.WebSocketCloseSentIsEnabled())
 92            //{
 93            //    TD.WebSocketCloseSent(
 94            //        this.WebSocket.GetHashCode(),
 95            //        this.webSocketCloseDetails.OutputCloseStatus.ToString(),
 96            //        this.RemoteAddress != null ? this.RemoteAddress.ToString() : string.Empty);
 97            //}
 98
 99            try
 100            {
 11101                await CloseInternalAsync(token);
 11102            }
 103            catch (Exception ex)
 104            {
 0105                if (Fx.IsFatal(ex))
 106                {
 0107                    throw;
 108                }
 109
 0110                WebSocketHelper.ThrowCorrectException(ex, TimeoutHelper.GetOriginalTimeout(token), WebSocketHelper.Close
 0111            }
 112
 113            //if (TD.WebSocketConnectionClosedIsEnabled())
 114            //{
 115            //    TD.WebSocketConnectionClosed(this.WebSocket.GetHashCode());
 116            //}
 11117        }
 118
 119        protected override async Task CloseOutputSessionCoreAsync(CancellationToken token)
 120        {
 121            //if (TD.WebSocketCloseOutputSentIsEnabled())
 122            //{
 123            //    TD.WebSocketCloseOutputSent(
 124            //        this.WebSocket.GetHashCode(),
 125            //        this.webSocketCloseDetails.OutputCloseStatus.ToString(),
 126            //        this.RemoteAddress != null ? this.RemoteAddress.ToString() : string.Empty);
 127            //}
 128            try
 129            {
 11130                await CloseOutputAsync(CancellationToken.None);
 11131            }
 132            catch (Exception ex)
 133            {
 0134                if (Fx.IsFatal(ex))
 135                {
 0136                    throw;
 137                }
 138
 0139                WebSocketHelper.ThrowCorrectException(ex, TimeoutHelper.GetOriginalTimeout(token), WebSocketHelper.Close
 0140            }
 11141        }
 142
 143        protected override async Task OnCloseAsync(CancellationToken token)
 144        {
 145            try
 146            {
 11147                await base.OnCloseAsync(token);
 11148            }
 149            finally
 150            {
 11151                Cleanup();
 152            }
 11153        }
 154
 155        protected override void ReturnConnectionIfNecessary(bool abort, CancellationToken token)
 156        {
 11157        }
 158
 159        protected override Task CloseOutputAsync(CancellationToken token)
 160        {
 11161            Task task = CloseOutputImplAsync(token);
 11162            return task.ContinueWith(t =>
 11163            {
 11164                try
 11165                {
 11166                    WebSocketHelper.ThrowExceptionOnTaskFailure(t, TimeoutHelper.GetOriginalTimeout(token), WebSocketHel
 11167                }
 0168                catch (Exception error)
 11169                {
 0170                    Fx.Exception.TraceHandledException(error, TraceEventType.Information);
 0171                    throw;
 11172                }
 22173            });
 174        }
 175
 176        [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2219:Do not raise exceptions in finally clauses", J
 177        protected override async Task OnSendCoreAsync(Message message, CancellationToken token)
 178        {
 179            Fx.Assert(message != null, "message should not be null.");
 180
 15181            WebSocketMessageType outgoingMessageType = GetWebSocketMessageType(message);
 15182            if (IsStreamedOutput)
 183            {
 6184                WebSocketStream webSocketStream = new WebSocketStream(WebSocket, outgoingMessageType, token);
 6185                TimeoutStream timeoutStream = new TimeoutStream(webSocketStream, token);
 6186                await MessageEncoder.WriteMessageAsync(message, timeoutStream);
 6187                await webSocketStream.WriteEndOfMessageAsync(token);
 6188            }
 189            else
 190            {
 9191                ArraySegment<byte> messageData = EncodeMessage(message);
 9192                bool success = false;
 193                try
 194                {
 195                    //if (TD.WebSocketAsyncWriteStartIsEnabled())
 196                    //{
 197                    //    TD.WebSocketAsyncWriteStart(
 198                    //        this.WebSocket.GetHashCode(),
 199                    //        messageData.Count,
 200                    //        this.RemoteAddress != null ? this.RemoteAddress.ToString() : string.Empty);
 201                    //}
 202
 203                    try
 204                    {
 9205                        await WebSocket.SendAsync(messageData, outgoingMessageType, true, token);
 9206                    }
 207                    catch (Exception ex)
 208                    {
 0209                        if (Fx.IsFatal(ex))
 210                        {
 0211                            throw;
 212                        }
 213
 0214                        WebSocketHelper.ThrowCorrectException(ex, TimeoutHelper.GetOriginalTimeout(token), WebSocketHelp
 0215                    }
 216
 217                    //if (TD.WebSocketAsyncWriteStopIsEnabled())
 218                    //{
 219                    //    TD.WebSocketAsyncWriteStop(this.webSocket.GetHashCode());
 220                    //}
 221
 9222                    success = true;
 9223                }
 224                finally
 225                {
 226                    try
 227                    {
 9228                        BufferManager.ReturnBuffer(messageData.Array);
 9229                    }
 0230                    catch (Exception ex)
 231                    {
 0232                        if (Fx.IsFatal(ex) || success)
 233                        {
 0234                            throw;
 235                        }
 236
 0237                        Fx.Exception.TraceUnhandledException(ex);
 0238                    }
 239                }
 240            }
 15241        }
 242
 243        protected override ArraySegment<byte> EncodeMessage(Message message)
 244        {
 9245            return MessageEncoder.WriteMessage(message, int.MaxValue, BufferManager, 0);
 246        }
 247
 248        protected void Cleanup()
 249        {
 11250            if (Interlocked.CompareExchange(ref _cleanupStatus, WebSocketHelper.OperationFinished, WebSocketHelper.Opera
 251            {
 11252                OnCleanup();
 253            }
 11254        }
 255
 256        protected virtual void OnCleanup()
 257        {
 258            Fx.Assert(_cleanupStatus == WebSocketHelper.OperationFinished,
 259                "This method should only be called by this.Cleanup(). Make sure that you never call overriden OnCleanup(
 11260            if (_shouldDisposeWebSocketAfterClosed && _webSocket != null)
 261            {
 11262                _webSocket.Dispose();
 263            }
 11264        }
 265
 266        private static void ThrowOnPendingException(ref Exception pendingException)
 267        {
 26268            Exception exceptionToThrow = pendingException;
 269
 26270            if (exceptionToThrow != null)
 271            {
 0272                pendingException = null;
 0273                throw Fx.Exception.AsError(exceptionToThrow);
 274            }
 26275        }
 276
 277        private Task CloseInternalAsync(CancellationToken token)
 278        {
 279            try
 280            {
 11281                if (WebSocket.State == WebSocketState.Closed || WebSocket.State == WebSocketState.Aborted)
 11282                    return Task.CompletedTask;
 283
 0284                return WebSocket.CloseAsync(_webSocketCloseDetails.OutputCloseStatus, _webSocketCloseDetails.OutputClose
 285            }
 286            catch (Exception e)
 287            {
 0288                if (Fx.IsFatal(e))
 289                {
 0290                    throw;
 291                }
 292
 0293                throw WebSocketHelper.ConvertAndTraceException(e);
 294            }
 11295        }
 296
 297        private Task CloseOutputImplAsync(CancellationToken cancellationToken)
 298        {
 299            try
 300            {
 301                // Guard against calling CloseOutputAsync when the WebSocket has already sent or completed close.
 302                // This can happen if CloseAsync is called after the close handshake has already begun.
 11303                if (WebSocket.State == WebSocketState.Closed ||
 11304                    WebSocket.State == WebSocketState.Aborted ||
 11305                    WebSocket.State == WebSocketState.CloseSent)
 306                {
 0307                    return Task.CompletedTask;
 308                }
 309
 11310                return WebSocket.CloseOutputAsync(_webSocketCloseDetails.OutputCloseStatus, _webSocketCloseDetails.Outpu
 311            }
 312            catch (Exception e)
 313            {
 0314                if (Fx.IsFatal(e))
 315                {
 0316                    throw;
 317                }
 318
 0319                throw WebSocketHelper.ConvertAndTraceException(e);
 320            }
 11321        }
 322
 323        private static WebSocketMessageType GetWebSocketMessageType(Message message)
 324        {
 15325            WebSocketMessageType outgoingMessageType = WebSocketDefaults.DefaultWebSocketMessageType;
 15326            if (WebSocketMessageProperty.TryGet(message.Properties, out WebSocketMessageProperty webSocketMessagePropert
 327            {
 0328                outgoingMessageType = webSocketMessageProperty.MessageType;
 329            }
 330
 15331            return outgoingMessageType;
 332        }
 333
 334        protected class WebSocketMessageSource : IMessageSource
 335        {
 0336            private static readonly Action<object> s_onAsyncReceiveCancelled = Fx.ThunkCallback<object>(OnAsyncReceiveCa
 337            private MessageEncoder _encoder;
 338            private BufferManager _bufferManager;
 339            private EndpointAddress _localAddress;
 340
 0341            public WebSocketMessageSource(EndpointAddress localAddress)
 342            {
 0343                _localAddress = localAddress;
 0344            }
 345
 346            private Message _pendingMessage;
 347            private Exception _pendingException;
 348            private readonly WebSocketContext _context;
 349            private WebSocket _webSocket;
 350            private bool _closureReceived = false;
 351            private bool _useStreaming;
 352            private int _receiveBufferSize;
 353            private int _maxBufferSize;
 354            private long _maxReceivedMessageSize;
 355            private TaskCompletionSource<object> _streamWaitTask;
 356            private IDefaultCommunicationTimeouts _defaultTimeouts;
 357            private SecurityMessageProperty _handshakeSecurityMessageProperty;
 358            private WebSocketCloseDetails _closeDetails;
 359            private readonly ReadOnlyDictionary<string, object> _properties;
 360            private TimeSpan _asyncReceiveTimeout;
 361            private TaskCompletionSource<object> _receiveTask;
 362            private int _asyncReceiveState;
 363
 0364            public WebSocketMessageSource(WebSocketTransportDuplexSessionChannel webSocketTransportDuplexSessionChannel,
 0365                    bool useStreaming, IDefaultCommunicationTimeouts defaultTimeouts)
 366            {
 0367                Initialize(webSocketTransportDuplexSessionChannel, webSocket, useStreaming, defaultTimeouts);
 368                // TODO: Switch IMessageSource to use TimeSpan instead of CancellationToken. See Issue #283
 0369                _asyncReceiveTimeout = TimeSpan.Zero;
 0370                StartNextReceiveAsync();
 0371            }
 372
 11373            public WebSocketMessageSource(WebSocketTransportDuplexSessionChannel webSocketTransportDuplexSessionChannel,
 11374                bool isStreamed, RemoteEndpointMessageProperty remoteEndpointMessageProperty, IDefaultCommunicationTimeo
 375            {
 11376                Initialize(webSocketTransportDuplexSessionChannel, context.WebSocket, isStreamed, defaultTimeouts);
 377
 11378                IPrincipal user = requestContext?.User;
 11379                _context = new ServiceWebSocketContext(context, user);
 11380                RemoteEndpointMessageProperty = remoteEndpointMessageProperty;
 381                // Copy any string keyed items from requestContext to properties. This is an attempt to mimic HttpReques
 11382                var properties = new Dictionary<string, object>();
 44383                foreach (KeyValuePair<object, object> kv in requestContext.Items)
 384                {
 11385                    if (kv.Key is string key)
 386                    {
 11387                        properties[key] = kv.Value;
 388                    }
 389                }
 390
 11391                _properties = requestContext == null ? null : new ReadOnlyDictionary<string, object>(properties);
 392
 11393                StartNextReceiveAsync();
 11394            }
 395
 396            private void Initialize(WebSocketTransportDuplexSessionChannel webSocketTransportDuplexSessionChannel, WebSo
 397            {
 11398                _webSocket = webSocket;
 11399                _encoder = webSocketTransportDuplexSessionChannel.MessageEncoder;
 11400                _bufferManager = webSocketTransportDuplexSessionChannel.BufferManager;
 11401                _localAddress = webSocketTransportDuplexSessionChannel.LocalAddress;
 11402                _maxBufferSize = webSocketTransportDuplexSessionChannel.MaxBufferSize;
 11403                _handshakeSecurityMessageProperty = webSocketTransportDuplexSessionChannel.RemoteSecurity;
 11404                _maxReceivedMessageSize = webSocketTransportDuplexSessionChannel.TransportFactorySettings.MaxReceivedMes
 11405                _receiveBufferSize = Math.Min(WebSocketHelper.GetReceiveBufferSize(_maxReceivedMessageSize), _maxBufferS
 11406                _useStreaming = useStreaming;
 11407                _defaultTimeouts = defaultTimeouts;
 11408                _closeDetails = webSocketTransportDuplexSessionChannel._webSocketCloseDetails;
 11409                _asyncReceiveState = AsyncReceiveState.Finished;
 11410            }
 411
 32412            internal RemoteEndpointMessageProperty RemoteEndpointMessageProperty { get; }
 413
 414            private static void OnAsyncReceiveCancelled(object target)
 415            {
 0416                WebSocketMessageSource messageSource = (WebSocketMessageSource)target;
 0417                messageSource.AsyncReceiveCancelled();
 0418            }
 419
 420            private void AsyncReceiveCancelled()
 421            {
 0422                if (Interlocked.CompareExchange(ref _asyncReceiveState, AsyncReceiveState.Cancelled, AsyncReceiveState.S
 423                {
 0424                    _receiveTask.SetResult(null);
 425                }
 0426            }
 427
 428            public async Task<Message> ReceiveAsync(CancellationToken token)
 429            {
 26430                if (!_receiveTask.Task.IsCompleted)
 431                {
 26432                    using (token.Register(() => AsyncReceiveCancelled()))
 433                    {
 26434                        await _receiveTask.Task;
 26435                    }
 436                }
 437
 26438                if (_asyncReceiveState == AsyncReceiveState.Cancelled)
 439                {
 0440                    throw Fx.Exception.AsError(WebSocketHelper.GetTimeoutException(null, TimeoutHelper.GetOriginalTimeou
 441                }
 442                else
 443                {
 444                    Fx.Assert(_asyncReceiveState == AsyncReceiveState.Finished, "this.asyncReceiveState is not AsyncRece
 26445                    Message message = GetPendingMessage();
 446
 26447                    if (message != null)
 448                    {
 449                        // If we get any exception thrown out before that, the channel will be aborted thus no need to m
 15450                        StartNextReceiveAsync();
 451                    }
 452
 26453                    return message;
 454                }
 26455            }
 456
 457            public void UpdateOpenNotificationMessageProperties(MessageProperties messageProperties)
 458            {
 1459                AddMessageProperties(messageProperties, WebSocketDefaults.DefaultWebSocketMessageType);
 1460            }
 461
 462            private async Task ReadBufferedMessageAsync()
 463            {
 18464                byte[] internalBuffer = null;
 465                try
 466                {
 18467                    internalBuffer = _bufferManager.TakeBuffer(_receiveBufferSize);
 468
 18469                    int receivedByteCount = 0;
 18470                    bool endOfMessage = false;
 18471                    WebSocketReceiveResult result = null;
 472                    do
 473                    {
 474                        try
 475                        {
 476                            //if (TD.WebSocketAsyncReadStartIsEnabled())
 477                            //{
 478                            //    TD.WebSocketAsyncReadStart(this.webSocket.GetHashCode());
 479                            //}
 480
 18481                            Task<WebSocketReceiveResult> receiveTask = _webSocket.ReceiveAsync(
 18482                                                            new ArraySegment<byte>(internalBuffer, receivedByteCount, in
 18483                                                            CancellationToken.None);
 484
 18485                            await receiveTask.ConfigureAwait(false);
 486
 18487                            result = receiveTask.Result;
 18488                            CheckCloseStatus(result);
 18489                            endOfMessage = result.EndOfMessage;
 490
 18491                            receivedByteCount += result.Count;
 18492                            if (receivedByteCount >= internalBuffer.Length && !result.EndOfMessage)
 493                            {
 0494                                if (internalBuffer.Length >= _maxBufferSize)
 495                                {
 0496                                    _pendingException = Fx.Exception.AsError(new QuotaExceededException(SR.Format(SR.Max
 0497                                    return;
 498                                }
 499
 0500                                int newSize = (int)Math.Min(((double)internalBuffer.Length) * 2, _maxBufferSize);
 501                                Fx.Assert(newSize > 0, "buffer size should be larger than zero.");
 0502                                byte[] newBuffer = _bufferManager.TakeBuffer(newSize);
 0503                                Buffer.BlockCopy(internalBuffer, 0, newBuffer, 0, receivedByteCount);
 0504                                _bufferManager.ReturnBuffer(internalBuffer);
 0505                                internalBuffer = newBuffer;
 506                            }
 507
 508                            //if (TD.WebSocketAsyncReadStopIsEnabled())
 509                            //{
 510                            //    TD.WebSocketAsyncReadStop(
 511                            //        this.webSocket.GetHashCode(),
 512                            //        receivedByteCount,
 513                            //        TraceUtility.GetRemoteEndpointAddressPort(this.RemoteEndpointMessageProperty));
 514                            //}
 18515                        }
 516                        catch (AggregateException ex)
 517                        {
 0518                            WebSocketHelper.ThrowCorrectException(ex, TimeSpan.MaxValue, WebSocketHelper.ReceiveOperatio
 0519                        }
 520                    }
 18521                    while (!endOfMessage && !_closureReceived);
 522
 18523                    byte[] buffer = null;
 18524                    bool success = false;
 525                    try
 526                    {
 18527                        buffer = _bufferManager.TakeBuffer(receivedByteCount);
 18528                        Buffer.BlockCopy(internalBuffer, 0, buffer, 0, receivedByteCount);
 529                        Fx.Assert(result != null, "Result should not be null");
 18530                        _pendingMessage = await PrepareMessageAsync(result, buffer, receivedByteCount);
 18531                        success = true;
 18532                    }
 533                    finally
 534                    {
 18535                        if (buffer != null && (!success || _pendingMessage == null))
 536                        {
 9537                            _bufferManager.ReturnBuffer(buffer);
 538                        }
 539                    }
 18540                }
 0541                catch (Exception ex)
 542                {
 0543                    if (Fx.IsFatal(ex))
 544                    {
 0545                        throw;
 546                    }
 547
 0548                    _pendingException = WebSocketHelper.ConvertAndTraceException(ex, TimeSpan.MaxValue, WebSocketHelper.
 0549                }
 550                finally
 551                {
 18552                    if (internalBuffer != null)
 553                    {
 18554                        _bufferManager.ReturnBuffer(internalBuffer);
 555                    }
 556                }
 18557            }
 558
 559            public async Task<bool> WaitForMessageAsync(CancellationToken token)
 560            {
 561                try
 562                {
 0563                    _pendingMessage = await ReceiveAsync(token);
 0564                    return true;
 565                }
 0566                catch (TimeoutException ex)
 567                {
 568                    //if (TD.ReceiveTimeoutIsEnabled())
 569                    //{
 570                    //    TD.ReceiveTimeout(ex.Message);
 571                    //}
 572
 0573                    _pendingException = Fx.Exception.AsError(ex);
 0574                    DiagnosticUtility.TraceHandledException(ex, TraceEventType.Information);
 0575                    return false;
 576                }
 0577            }
 578
 579            internal void FinishUsingMessageStream(Exception ex)
 580            {
 581                //// The pattern of the task here is:
 582                //// 1) Only one thread can get the stream and consume the stream. A new task will be created at the mom
 583                //// 2) Only one another thread can enter the lock and wait on the task
 584                //// 3) The cleanup on the stream will return the stream to message source. And the cleanup call is limi
 6585                if (ex != null && _pendingException == null)
 586                {
 0587                    _pendingException = ex;
 588                }
 589
 6590                _streamWaitTask.SetResult(null);
 6591            }
 592
 593            internal void CheckCloseStatus(WebSocketReceiveResult result)
 594            {
 70595                if (result.MessageType == WebSocketMessageType.Close)
 596                {
 597                    //if (TD.WebSocketCloseStatusReceivedIsEnabled())
 598                    //{
 599                    //    TD.WebSocketCloseStatusReceived(
 600                    //        this.webSocket.GetHashCode(),
 601                    //        result.CloseStatus.ToString());
 602                    //}
 603
 11604                    _closureReceived = true;
 11605                    _closeDetails.InputCloseStatus = result.CloseStatus;
 11606                    _closeDetails.InputCloseStatusDescription = result.CloseStatusDescription;
 607                }
 70608            }
 609
 610            private async void StartNextReceiveAsync()
 611            {
 612                Fx.Assert(_receiveTask == null || _receiveTask.Task.IsCompleted, "this.receiveTask is not completed.");
 26613                _receiveTask = new TaskCompletionSource<object>();
 26614                int currentState = Interlocked.CompareExchange(ref _asyncReceiveState, AsyncReceiveState.Started, AsyncR
 615                Fx.Assert(currentState == AsyncReceiveState.Finished, "currentState is not AsyncReceiveState.Finished: "
 26616                if (currentState != AsyncReceiveState.Finished)
 617                {
 0618                    throw Fx.Exception.AsError(new InvalidOperationException());
 619                }
 620
 621                try
 622                {
 26623                    if (_useStreaming)
 624                    {
 8625                        if (_streamWaitTask != null)
 626                        {
 627                            //// Wait until the previous stream message finished.
 628
 6629                            await _streamWaitTask.Task.ConfigureAwait(false);
 630                        }
 631
 8632                        _streamWaitTask = new TaskCompletionSource<object>();
 633                    }
 634
 26635                    if (_pendingException == null)
 636                    {
 26637                        if (!_useStreaming)
 638                        {
 18639                            await ReadBufferedMessageAsync().ConfigureAwait(false);
 640                        }
 641                        else
 642                        {
 8643                            byte[] buffer = _bufferManager.TakeBuffer(_receiveBufferSize);
 8644                            bool success = false;
 645                            try
 646                            {
 647                                //if (TD.WebSocketAsyncReadStartIsEnabled())
 648                                //{
 649                                //    TD.WebSocketAsyncReadStart(this.webSocket.GetHashCode());
 650                                //}
 651
 652                                try
 653                                {
 8654                                    Task<WebSocketReceiveResult> receiveTask = _webSocket.ReceiveAsync(
 8655                                                        new ArraySegment<byte>(buffer, 0, _receiveBufferSize),
 8656                                                        CancellationToken.None);
 657
 8658                                    await receiveTask.ConfigureAwait(false);
 659
 8660                                    WebSocketReceiveResult result = receiveTask.Result;
 8661                                    CheckCloseStatus(result);
 8662                                    _pendingMessage = await PrepareMessageAsync(result, buffer, result.Count);
 663
 664                                    //if (TD.WebSocketAsyncReadStopIsEnabled())
 665                                    //{
 666                                    //    TD.WebSocketAsyncReadStop(
 667                                    //        this.webSocket.GetHashCode(),
 668                                    //        result.Count,
 669                                    //        TraceUtility.GetRemoteEndpointAddressPort(this.remoteEndpointMessageProper
 670                                    //}
 8671                                }
 672                                catch (AggregateException ex)
 673                                {
 0674                                    WebSocketHelper.ThrowCorrectException(ex, _asyncReceiveTimeout, WebSocketHelper.Rece
 0675                                }
 8676                                success = true;
 8677                            }
 0678                            catch (Exception ex)
 679                            {
 0680                                if (Fx.IsFatal(ex))
 681                                {
 0682                                    throw;
 683                                }
 684
 0685                                _pendingException = WebSocketHelper.ConvertAndTraceException(ex, _asyncReceiveTimeout, W
 0686                            }
 687                            finally
 688                            {
 8689                                if (!success)
 690                                {
 0691                                    _bufferManager.ReturnBuffer(buffer);
 692                                }
 693                            }
 8694                        }
 695                    }
 26696                }
 697                finally
 698                {
 26699                    if (Interlocked.CompareExchange(ref _asyncReceiveState, AsyncReceiveState.Finished, AsyncReceiveStat
 700                    {
 26701                        _receiveTask.SetResult(null);
 702                    }
 703                }
 26704            }
 705
 706            private void AddMessageProperties(MessageProperties messageProperties, WebSocketMessageType incomingMessageT
 707            {
 708                Fx.Assert(messageProperties != null, "messageProperties should not be null.");
 16709                WebSocketMessageProperty messageProperty = new WebSocketMessageProperty(
 16710                                                                _context,
 16711                                                                _webSocket.SubProtocol,
 16712                                                                incomingMessageType,
 16713                                                                _properties);
 16714                messageProperties.Add(WebSocketMessageProperty.Name, messageProperty);
 715
 16716                if (RemoteEndpointMessageProperty != null)
 717                {
 16718                    messageProperties.Add(RemoteEndpointMessageProperty.Name, RemoteEndpointMessageProperty);
 719                }
 720
 16721                if (_handshakeSecurityMessageProperty != null)
 722                {
 0723                    messageProperties.Security = (SecurityMessageProperty)_handshakeSecurityMessageProperty.CreateCopy()
 724                }
 16725            }
 726
 727            private Message GetPendingMessage()
 728            {
 26729                ThrowOnPendingException(ref _pendingException);
 730
 26731                if (_pendingMessage != null)
 732                {
 15733                    Message pendingMessage = _pendingMessage;
 15734                    _pendingMessage = null;
 15735                    return pendingMessage;
 736                }
 737
 11738                return null;
 739            }
 740
 741            private async Task<Message> PrepareMessageAsync(WebSocketReceiveResult result, byte[] buffer, int count)
 742            {
 26743                if (result.MessageType != WebSocketMessageType.Close)
 744                {
 745                    Message message;
 15746                    if (_useStreaming)
 747                    {
 6748                        TimeoutHelper readTimeoutHelper = new TimeoutHelper(_defaultTimeouts.ReceiveTimeout);
 6749                        message = await _encoder.ReadMessageAsync(
 6750                            new MaxMessageSizeStream(
 6751                                new TimeoutStream(
 6752                                    new WebSocketStream(
 6753                                        this,
 6754                                        new ArraySegment<byte>(buffer, 0, count),
 6755                                        _webSocket,
 6756                                        result.EndOfMessage,
 6757                                        _bufferManager,
 6758                                        new TimeoutHelper(_defaultTimeouts.CloseTimeout).GetCancellationToken()),
 6759                                    readTimeoutHelper.GetCancellationToken()),
 6760                                _maxReceivedMessageSize),
 6761                            _maxBufferSize);
 762                    }
 763                    else
 764                    {
 9765                        ArraySegment<byte> bytes = new ArraySegment<byte>(buffer, 0, count);
 9766                        message = _encoder.ReadMessage(bytes, _bufferManager);
 767                    }
 768
 15769                    if (message.Version.Addressing != AddressingVersion.None || !_localAddress.IsAnonymous)
 770                    {
 15771                        _localAddress.ApplyTo(message);
 772                    }
 773
 15774                    if (message.Version.Addressing == AddressingVersion.None && message.Headers.Action == null)
 775                    {
 0776                        if (result.MessageType == WebSocketMessageType.Binary)
 777                        {
 0778                            message.Headers.Action = WebSocketTransportSettings.BinaryMessageReceivedAction;
 779                        }
 780                        else
 781                        {
 782                            // WebSocketMesssageType should always be binary or text at this moment. The layer below us 
 783                            Fx.Assert(result.MessageType == WebSocketMessageType.Text, "result.MessageType must be WebSo
 0784                            message.Headers.Action = WebSocketTransportSettings.TextMessageReceivedAction;
 785                        }
 786                    }
 787
 15788                    if (message != null)
 789                    {
 15790                        AddMessageProperties(message.Properties, result.MessageType);
 791                    }
 792
 15793                    return message;
 794                }
 795
 11796                return null;
 26797            }
 798
 799            private static class AsyncReceiveState
 800            {
 801                internal const int Started = 0;
 802                internal const int Finished = 1;
 803                internal const int Cancelled = 2;
 804            }
 805        }
 806
 807        private class WebSocketStream : Stream
 808        {
 809            private readonly WebSocket _webSocket;
 810            private readonly WebSocketMessageSource _messageSource;
 811            private CancellationToken _closeToken;
 812            private ArraySegment<byte> _initialReadBuffer;
 813            private bool _endOfMessageReached = false;
 814            private readonly bool _isForRead;
 815            private bool _endofMessageReceived;
 816            private readonly WebSocketMessageType _outgoingMessageType;
 817            private readonly BufferManager _bufferManager;
 818            private int _messageSourceCleanState;
 819            private int _endOfMessageWritten;
 820            private int _readTimeout;
 821            private int _writeTimeout;
 822
 823            public WebSocketStream(
 824                        WebSocketMessageSource messageSource,
 825                        ArraySegment<byte> initialBuffer,
 826                        WebSocket webSocket,
 827                        bool endofMessageReceived,
 828                        BufferManager bufferManager,
 829                        CancellationToken closeToken)
 6830                : this(webSocket, WebSocketDefaults.DefaultWebSocketMessageType, closeToken)
 831            {
 832                Fx.Assert(messageSource != null, "messageSource should not be null.");
 6833                _messageSource = messageSource;
 6834                _initialReadBuffer = initialBuffer;
 6835                _isForRead = true;
 6836                _endofMessageReceived = endofMessageReceived;
 6837                _bufferManager = bufferManager;
 6838                _messageSourceCleanState = WebSocketHelper.OperationNotStarted;
 6839                _endOfMessageWritten = WebSocketHelper.OperationNotStarted;
 6840            }
 841
 12842            public WebSocketStream(
 12843                    WebSocket webSocket,
 12844                    WebSocketMessageType outgoingMessageType,
 12845                    CancellationToken closeToken)
 846            {
 847                Fx.Assert(webSocket != null, "webSocket should not be null.");
 12848                _webSocket = webSocket;
 12849                _isForRead = false;
 12850                _outgoingMessageType = outgoingMessageType;
 12851                _messageSourceCleanState = WebSocketHelper.OperationFinished;
 12852                _closeToken = closeToken;
 12853            }
 854
 855            public override bool CanRead
 856            {
 0857                get { return _isForRead; }
 858            }
 859
 860            public override bool CanSeek
 861            {
 0862                get { return false; }
 863            }
 864
 865            public override bool CanTimeout
 866            {
 867                get
 868                {
 12869                    return true;
 870                }
 871            }
 872
 873            public override bool CanWrite
 874            {
 3875                get { return !_isForRead; }
 876            }
 877
 878            public override long Length
 879            {
 0880                get { throw Fx.Exception.AsError(new NotSupportedException(SR.SeekNotSupported)); }
 881            }
 882
 883            public override long Position
 884            {
 885                get
 886                {
 0887                    throw Fx.Exception.AsError(new NotSupportedException(SR.SeekNotSupported));
 888                }
 889
 890                set
 891                {
 0892                    throw Fx.Exception.AsError(new NotSupportedException(SR.SeekNotSupported));
 893                }
 894            }
 895
 896            public override int ReadTimeout
 897            {
 898                get
 899                {
 12900                    return _readTimeout;
 901                }
 902
 903                set
 904                {
 905                    Fx.Assert(value >= 0, "ReadTimeout should not be negative.");
 12906                    _readTimeout = value;
 12907                }
 908            }
 909
 910            public override int WriteTimeout
 911            {
 912                get
 913                {
 0914                    return _writeTimeout;
 915                }
 916
 917                set
 918                {
 919                    Fx.Assert(value >= 0, "WriteTimeout should not be negative.");
 12920                    _writeTimeout = value;
 12921                }
 922            }
 923
 924            public override void Close()
 925            {
 6926                base.Close();
 927                // There's no async close on Stream
 6928                CleanupAsync(_closeToken).GetAwaiter().GetResult();
 6929            }
 930
 931            public override void Flush()
 932            {
 15933            }
 934
 935            public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object 
 936            {
 0937                return ReadAsync(buffer, offset, count).ToApm(callback, state);
 938            }
 939
 940            public override int EndRead(IAsyncResult asyncResult)
 941            {
 0942                return asyncResult.ToApmEnd<int>();
 943            }
 944
 945            public override int Read(byte[] buffer, int offset, int count)
 946            {
 0947                return ReadAsync(buffer, offset, count).GetAwaiter().GetResult();
 948            }
 949
 950            public override async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellati
 951            {
 952                Fx.Assert(_messageSource != null, "messageSource should not be null in read case.");
 953                Fx.Assert(cancellationToken.CanBeCanceled, "WebSocketStream should be wrapped by TimeoutStream which sho
 245954                cancellationToken.ThrowIfCancellationRequested();
 955
 245956                if (_endOfMessageReached)
 957                {
 17958                    return 0;
 959                }
 960
 228961                if (_initialReadBuffer.Count != 0)
 962                {
 184963                    return GetBytesFromInitialReadBuffer(buffer, offset, count);
 964                }
 965
 44966                int receivedBytes = 0;
 44967                if (_endofMessageReceived)
 968                {
 0969                    _endOfMessageReached = true;
 970                }
 971                else
 972                {
 973                    //if (TD.WebSocketAsyncReadStartIsEnabled())
 974                    //{
 975                    //    TD.WebSocketAsyncReadStart(this.webSocket.GetHashCode());
 976                    //}
 977
 44978                    WebSocketReceiveResult result = null;
 979                    try
 980                    {
 44981                        result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer, offset, count), cancellati
 44982                    }
 983                    catch (Exception ex)
 984                    {
 0985                        if (Fx.IsFatal(ex))
 986                        {
 0987                            throw;
 988                        }
 989
 0990                        WebSocketHelper.ThrowCorrectException(ex, TimeoutHelper.GetOriginalTimeout(cancellationToken), W
 0991                    }
 992
 44993                    if (result.EndOfMessage)
 994                    {
 6995                        _endofMessageReceived = true;
 6996                        _endOfMessageReached = true;
 997                    }
 998
 44999                    receivedBytes = result.Count;
 441000                    CheckResultAndEnsureNotCloseMessage(_messageSource, result);
 1001
 1002                    //if (TD.WebSocketAsyncReadStopIsEnabled())
 1003                    //{
 1004                    //    TD.WebSocketAsyncReadStop(
 1005                    //        this.webSocket.GetHashCode(),
 1006                    //        receivedBytes,
 1007                    //        this.messageSource != null ? TraceUtility.GetRemoteEndpointAddressPort(this.messageSource.
 1008                    //}
 441009                }
 1010
 441011                if (_endOfMessageReached)
 1012                {
 61013                    await CleanupAsync(cancellationToken);
 1014                }
 1015
 441016                return receivedBytes;
 2451017            }
 1018
 1019            public override long Seek(long offset, SeekOrigin origin)
 1020            {
 01021                throw Fx.Exception.AsError(new NotSupportedException());
 1022            }
 1023
 1024            public override void SetLength(long value)
 1025            {
 01026                throw Fx.Exception.AsError(new NotSupportedException());
 1027            }
 1028
 1029            public override void Write(byte[] buffer, int offset, int count)
 1030            {
 01031                WriteAsync(buffer, offset, count).GetAwaiter().GetResult();
 01032            }
 1033
 1034            public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationTo
 1035            {
 121036                if (_endOfMessageWritten == WebSocketHelper.OperationFinished)
 1037                {
 01038                    throw Fx.Exception.AsError(new InvalidOperationException(SR.WebSocketStreamWriteCalledAfterEOMSent))
 1039                }
 1040
 1041                Fx.Assert(cancellationToken.CanBeCanceled, "WebSocketStream should be wrapped by TimeoutStream which sho
 121042                cancellationToken.ThrowIfCancellationRequested();
 1043
 121044                cancellationToken.ThrowIfCancellationRequested();
 1045                //if (TD.WebSocketAsyncWriteStartIsEnabled())
 1046                //{
 1047                //    TD.WebSocketAsyncWriteStart(
 1048                //            this.webSocket.GetHashCode(),
 1049                //            count,
 1050                //            this.messageSource != null ? TraceUtility.GetRemoteEndpointAddressPort(this.messageSource.
 1051                //}
 1052
 1053                try
 1054                {
 121055                    await _webSocket.SendAsync(new ArraySegment<byte>(buffer, offset, count), _outgoingMessageType, fals
 121056                }
 1057                catch (Exception ex)
 1058                {
 01059                    if (Fx.IsFatal(ex))
 1060                    {
 01061                        throw;
 1062                    }
 1063
 01064                    WebSocketHelper.ThrowCorrectException(ex, TimeoutHelper.GetOriginalTimeout(cancellationToken), WebSo
 01065                }
 1066
 1067                //if (TD.WebSocketAsyncWriteStopIsEnabled())
 1068                //{
 1069                //    TD.WebSocketAsyncWriteStop(this.webSocket.GetHashCode());
 1070                //}
 121071            }
 1072
 1073            public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object
 1074            {
 01075                return WriteAsync(buffer, offset, count).ToApm(callback, state);
 1076            }
 1077
 1078            public override void EndWrite(IAsyncResult asyncResult)
 1079            {
 01080                asyncResult.ToApmEnd();
 01081            }
 1082
 1083            public async Task WriteEndOfMessageAsync(CancellationToken cancellationToken)
 1084            {
 1085                //if (TD.WebSocketAsyncWriteStartIsEnabled())
 1086                //{
 1087                //    TD.WebSocketAsyncWriteStart(
 1088                //            this.webSocket.GetHashCode(),
 1089                //            0,
 1090                //            this.messageSource != null ? TraceUtility.GetRemoteEndpointAddressPort(this.messageSource.
 1091                //}
 1092
 61093                if (Interlocked.CompareExchange(ref _endOfMessageWritten, WebSocketHelper.OperationFinished, WebSocketHe
 1094                {
 1095                    try
 1096                    {
 61097                        await _webSocket.SendAsync(new ArraySegment<byte>(Array.Empty<byte>(), 0, 0), _outgoingMessageTy
 61098                    }
 1099                    catch (Exception ex)
 1100                    {
 01101                        if (Fx.IsFatal(ex))
 1102                        {
 01103                            throw;
 1104                        }
 1105
 01106                        WebSocketHelper.ThrowCorrectException(ex, TimeoutHelper.GetOriginalTimeout(cancellationToken), W
 01107                    }
 1108                }
 1109
 1110                //if (TD.WebSocketAsyncWriteStopIsEnabled())
 1111                //{
 1112                //    TD.WebSocketAsyncWriteStop(this.webSocket.GetHashCode());
 1113                //}
 61114            }
 1115
 1116            private static void CheckResultAndEnsureNotCloseMessage(WebSocketMessageSource messageSource, WebSocketRecei
 1117            {
 441118                messageSource.CheckCloseStatus(result);
 441119                if (result.MessageType == WebSocketMessageType.Close)
 1120                {
 01121                    throw Fx.Exception.AsError(new ProtocolException(SR.WebSocketUnexpectedCloseMessageError));
 1122                }
 441123            }
 1124
 1125            private int GetBytesFromInitialReadBuffer(byte[] buffer, int offset, int count)
 1126            {
 1841127                int bytesToCopy = _initialReadBuffer.Count > count ? count : _initialReadBuffer.Count;
 1841128                Buffer.BlockCopy(_initialReadBuffer.Array, _initialReadBuffer.Offset, buffer, offset, bytesToCopy);
 1841129                _initialReadBuffer = new ArraySegment<byte>(_initialReadBuffer.Array, _initialReadBuffer.Offset + bytesT
 1841130                return bytesToCopy;
 1131            }
 1132
 1133            private async Task CleanupAsync(CancellationToken cancellationToken)
 1134            {
 121135                if (_isForRead)
 1136                {
 121137                    if (Interlocked.CompareExchange(ref _messageSourceCleanState, WebSocketHelper.OperationFinished, Web
 1138                    {
 61139                        Exception pendingException = null;
 1140                        try
 1141                        {
 61142                            if (!_endofMessageReceived && (_webSocket.State == WebSocketState.Open || _webSocket.State =
 1143                            {
 1144                                // Drain the reading stream
 1145                                do
 1146                                {
 1147                                    try
 1148                                    {
 01149                                        WebSocketReceiveResult receiveResult = await _webSocket.ReceiveAsync(new ArraySe
 01150                                        _endofMessageReceived = receiveResult.EndOfMessage;
 01151                                    }
 1152                                    catch (Exception ex)
 1153                                    {
 01154                                        if (Fx.IsFatal(ex))
 1155                                        {
 01156                                            throw;
 1157                                        }
 1158
 01159                                        WebSocketHelper.ThrowCorrectException(ex, TimeoutHelper.GetOriginalTimeout(cance
 01160                                    }
 1161                                }
 01162                                while (!_endofMessageReceived && (_webSocket.State == WebSocketState.Open || _webSocket.
 1163                            }
 61164                        }
 01165                        catch (Exception ex)
 1166                        {
 01167                            if (Fx.IsFatal(ex))
 1168                            {
 01169                                throw;
 1170                            }
 1171
 1172                            // Not throwing out this exception during stream cleanup. The exception
 1173                            // will be thrown out when we are trying to receive the next message using the same
 1174                            // WebSocket object.
 01175                            pendingException = WebSocketHelper.ConvertAndTraceException(ex, TimeoutHelper.GetOriginalTim
 01176                        }
 1177
 61178                        _bufferManager.ReturnBuffer(_initialReadBuffer.Array);
 1179                        Fx.Assert(_messageSource != null, "messageSource should not be null.");
 61180                        _messageSource.FinishUsingMessageStream(pendingException);
 61181                    }
 1182                }
 1183                else
 1184                {
 01185                    if (Interlocked.CompareExchange(ref _endOfMessageWritten, WebSocketHelper.OperationFinished, WebSock
 1186                    {
 01187                        await WriteEndOfMessageAsync(cancellationToken);
 1188                    }
 1189                }
 121190            }
 1191        }
 1192
 1193        private class WebSocketCloseDetails : IWebSocketCloseDetails
 1194        {
 111195            public WebSocketCloseStatus? InputCloseStatus { get; internal set; }
 1196
 111197            public string InputCloseStatusDescription { get; internal set; }
 1198
 221199            internal WebSocketCloseStatus OutputCloseStatus { get; private set; } = WebSocketCloseStatus.NormalClosure;
 1200
 111201            internal string OutputCloseStatusDescription { get; private set; }
 1202
 1203            public void SetOutputCloseStatus(WebSocketCloseStatus closeStatus, string closeStatusDescription)
 1204            {
 01205                OutputCloseStatus = closeStatus;
 01206                OutputCloseStatusDescription = closeStatusDescription;
 01207            }
 1208        }
 1209    }
 1210}

Methods/Properties

.ctor(CoreWCF.Channels.IHttpTransportFactorySettings,CoreWCF.EndpointAddress,System.Uri)
WebSocket()
WebSocket(System.Net.WebSockets.WebSocket)
WebSocketSettings()
TransferMode()
MaxBufferSize()
TransportFactorySettings()
ShouldDisposeWebSocketAfterClosed(System.Boolean)
OnAbort()
GetProperty()
CompleteCloseAsync()
CloseOutputSessionCoreAsync()
OnCloseAsync()
ReturnConnectionIfNecessary(System.Boolean,System.Threading.CancellationToken)
CloseOutputAsync(System.Threading.CancellationToken)
OnSendCoreAsync()
EncodeMessage(CoreWCF.Channels.Message)
Cleanup()
OnCleanup()
ThrowOnPendingException(System.Exception&)
CloseInternalAsync(System.Threading.CancellationToken)
CloseOutputImplAsync(System.Threading.CancellationToken)
GetWebSocketMessageType(CoreWCF.Channels.Message)
.cctor()
.ctor(CoreWCF.EndpointAddress)
.ctor(CoreWCF.Channels.WebSocketTransportDuplexSessionChannel,System.Net.WebSockets.WebSocket,System.Boolean,CoreWCF.IDefaultCommunicationTimeouts)
.ctor(CoreWCF.Channels.WebSocketTransportDuplexSessionChannel,System.Net.WebSockets.WebSocketContext,System.Boolean,CoreWCF.Channels.RemoteEndpointMessageProperty,CoreWCF.IDefaultCommunicationTimeouts,Microsoft.AspNetCore.Http.HttpContext)
Initialize(CoreWCF.Channels.WebSocketTransportDuplexSessionChannel,System.Net.WebSockets.WebSocket,System.Boolean,CoreWCF.IDefaultCommunicationTimeouts)
RemoteEndpointMessageProperty()
OnAsyncReceiveCancelled(System.Object)
AsyncReceiveCancelled()
ReceiveAsync()
UpdateOpenNotificationMessageProperties(CoreWCF.Channels.MessageProperties)
ReadBufferedMessageAsync()
WaitForMessageAsync()
FinishUsingMessageStream(System.Exception)
CheckCloseStatus(System.Net.WebSockets.WebSocketReceiveResult)
StartNextReceiveAsync()
AddMessageProperties(CoreWCF.Channels.MessageProperties,System.Net.WebSockets.WebSocketMessageType)
GetPendingMessage()
PrepareMessageAsync()
.ctor(CoreWCF.Channels.WebSocketTransportDuplexSessionChannel/WebSocketMessageSource,System.ArraySegment`1<System.Byte>,System.Net.WebSockets.WebSocket,System.Boolean,CoreWCF.Channels.BufferManager,System.Threading.CancellationToken)
.ctor(System.Net.WebSockets.WebSocket,System.Net.WebSockets.WebSocketMessageType,System.Threading.CancellationToken)
CanRead()
CanSeek()
CanTimeout()
CanWrite()
Length()
Position()
Position(System.Int64)
ReadTimeout()
ReadTimeout(System.Int32)
WriteTimeout()
WriteTimeout(System.Int32)
Close()
Flush()
BeginRead(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object)
EndRead(System.IAsyncResult)
Read(System.Byte[],System.Int32,System.Int32)
ReadAsync()
Seek(System.Int64,System.IO.SeekOrigin)
SetLength(System.Int64)
Write(System.Byte[],System.Int32,System.Int32)
WriteAsync()
BeginWrite(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object)
EndWrite(System.IAsyncResult)
WriteEndOfMessageAsync()
CheckResultAndEnsureNotCloseMessage(CoreWCF.Channels.WebSocketTransportDuplexSessionChannel/WebSocketMessageSource,System.Net.WebSockets.WebSocketReceiveResult)
GetBytesFromInitialReadBuffer(System.Byte[],System.Int32,System.Int32)
CleanupAsync()
InputCloseStatus()
InputCloseStatusDescription()
OutputCloseStatus()
OutputCloseStatusDescription()
SetOutputCloseStatus(System.Net.WebSockets.WebSocketCloseStatus,System.String)