Esempio n. 1
0
        internal async Task <WebSocketStream> AcceptAsync()
        {
            // Performance: Address Resolution (ARP) work-around: When we receive the control message from a TCP connection which hasn't had any
            // outbound traffic for 2 minutes the ARP cache no longer has the MAC address required to ACK the control message.  If we also begin
            // connecting a new socket at exactly the same time there's a known race condition (insert link here) where ARP can only resolve one
            // address at a time, which causes the loser of the race to have to retry after 3000ms.  To avoid the 3000ms delay we just pause for
            // a few ms here instead.
            await Task.Delay(TimeSpan.FromMilliseconds(2)).ConfigureAwait(false);

            var clientWebSocket = this.CreateWebSocket();

            // If we are accepting a sub-protocol handle that here
            var subProtocol = this.Response.Headers[HybridConnectionConstants.Headers.SecWebSocketProtocol];

            if (!string.IsNullOrEmpty(subProtocol))
            {
                clientWebSocket.Options.AddSubProtocol(subProtocol);
            }

            using (var cancelSource = new CancellationTokenSource(AcceptTimeout))
            {
                await clientWebSocket.ConnectAsync(this.wssRendezvousAddress, cancelSource.Token).ConfigureAwait(false);
            }

            var webSocketStream = new WebSocketStream(clientWebSocket, this.TrackingContext);

            return(webSocketStream);
        }
            public async Task AcceptConnectionAsync()
            {
                try
                {
                    // Performance: Address Resolution (ARP) work-around: When we receive the control message from a TCP connection which hasn't had any
                    // outbound traffic for 2 minutes the ARP cache no longer has the MAC address required to ACK the control message.  If we also begin
                    // connecting a new socket at exactly the same time there's a known race condition (insert link here) where ARP can only resolve one
                    // address at a time, which causes the loser of the race to have to retry after 3000ms.  To avoid the 3000ms delay we just pause for
                    // a few ms here instead.
                    await Task.Delay(TimeSpan.FromMilliseconds(2)).ConfigureAwait(false);

                    var timeoutHelper = new TimeoutHelper(AcceptTimeout);

                    var clientWebSocket = new ClientWebSocket45();
                    clientWebSocket.Options.SetBuffer(this.bufferSize, this.bufferSize);
                    clientWebSocket.Options.Host              = this.Address.Host;
                    clientWebSocket.Options.Proxy             = this.listener.Proxy;
                    clientWebSocket.Options.KeepAliveInterval = HybridConnectionConstants.KeepAliveInterval;

                    using (var cancelSource = new CancellationTokenSource(timeoutHelper.RemainingTime()))
                    {
                        await clientWebSocket.ConnectAsync(this.rendezvousAddress, cancelSource.Token).ConfigureAwait(false);
                    }

                    var webSocketStream = new WebSocketStream(clientWebSocket, this.TrackingContext);
                    this.AcceptSucceeded(webSocketStream);
                }
                catch (Exception exception)
                {
                    if (Fx.IsFatal(exception))
                    {
                        throw;
                    }

                    this.AcceptFailed(exception);
                }
            }