Пример #1
0
        public TestClient(bool synchronousCallbacks = false, IHubProtocol protocol = null, IInvocationBinder invocationBinder = null, bool addClaimId = false)
        {
            var pair = DuplexPipePair.GetConnectionTransport(synchronousCallbacks);

            Connection = new DefaultConnectionContext(Guid.NewGuid().ToString(), pair.Transport, pair.Application);

            // Add features SignalR needs for testing
            Connection.Features.Set <ITransferFormatFeature>(this);
            Connection.Features.Set <IConnectionHeartbeatFeature>(this);

            var claimValue = Interlocked.Increment(ref _id).ToString();
            var claims     = new List <Claim> {
                new Claim(ClaimTypes.Name, claimValue)
            };

            if (addClaimId)
            {
                claims.Add(new Claim(ClaimTypes.NameIdentifier, claimValue));
            }

            Connection.User = new ClaimsPrincipal(new ClaimsIdentity(claims));
            Connection.Items["ConnectedTask"] = new TaskCompletionSource <bool>();

            _protocol         = protocol ?? new JsonHubProtocol();
            _invocationBinder = invocationBinder ?? new DefaultInvocationBinder();

            _cts = new CancellationTokenSource();
        }
        public async ValueTask <ConnectionContext> StartAsync()
        {
            await _socket.ConnectAsync(_endpoint).ConfigureAwait(false);

            var pair = DuplexPipePair.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);

            LocalEndPoint  = _socket.LocalEndPoint;
            RemoteEndPoint = _socket.RemoteEndPoint;

            Transport    = pair.Transport;
            _application = pair.Application;

            _ = ExecuteAsync();
            return(this);
        }
Пример #3
0
        internal async Task ConnectInternalAsync(Func <WebSocketTransport, Task> connectFunc, CancellationToken cancellationToken)
        {
            CheckDisposed();

            TimerAwaitable timer     = null;
            Task           timerTask = null;

            try
            {
                // Pipes
                _duplexPipePair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);

                // Transport
                var transport = new WebSocketTransport(_duplexPipePair.Application, _logger);

                // Application
                _transportHandler = new TransportHandler(_duplexPipePair.Transport, _logger);

                // Session
                _session = new StreamingSession(_requestHandler, _transportHandler, _logger, cancellationToken);

                // Set up cancellation
                _disconnectCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);

                // Start transport and application
                var transportTask   = connectFunc(transport);
                var applicationTask = _transportHandler.ListenAsync(_disconnectCts.Token);
                var combinedTask    = Task.WhenAll(transportTask, applicationTask);

                Log.ClientStarted(_logger, _url ?? string.Empty);

                // Periodic task: keep alive
                // Disposed with `timer.Stop()` in the finally block below
                if (_keepAlive.HasValue)
                {
                    timer     = new TimerAwaitable(_keepAlive.Value, _keepAlive.Value);
                    timerTask = TimerLoopAsync(timer);
                }

                // We are connected!
                IsConnected = true;

                // Block until transport or application ends.
                await combinedTask.ConfigureAwait(false);

                // Signal that we're done
                _disconnectCts.Cancel();
                Log.ClientTransportApplicationCompleted(_logger, _url);
            }
            finally
            {
                timer?.Stop();

                if (timerTask != null)
                {
                    await timerTask.ConfigureAwait(false);
                }
            }

            Log.ClientCompleted(_logger, _url ?? string.Empty);
        }