Пример #1
0
        protected override Task <ContentProviderResult> GetCollapsibleContent(ContentProviderHttpRequest request)
        {
            string packageName = ExtractPackageName(request.RequestUri);

            if (!String.IsNullOrEmpty(packageName))
            {
                return(FetchPackage(packageName).Then(package =>
                {
                    if (package != null && package.d.results.Count > 0)
                    {
                        var packageInfo = package.d.results[0];
                        var projectIcon = String.Empty;
                        if (packageInfo.IconUrl != null)
                        {
                            projectIcon = String.Format("<img class=\"nuget-projecticon\" src=\"{0}\" />",
                                                        packageInfo.IconUrl);
                        }

                        var projectInfo = new StringBuilder();
                        projectInfo.AppendFormat("<div class=\"nuget-authors\" ><span>Authors: </span><div class=\"nuget-authors-entry\">{0}</div></div>",
                                                 packageInfo.Authors);
                        projectInfo.AppendFormat("<div class=\"nuget-downloads\" ><span># Downloads:</span> {0}</div>",
                                                 packageInfo.DownloadCount);

                        if (packageInfo.ProjectUrl != null)
                        {
                            projectInfo.AppendFormat(
                                "<div class=\"nuget-ProjectUrl\" ><a target=\"_blank\" href=\"{0}\">{0}</a></div>",
                                packageInfo.ProjectUrl);
                        }

                        return new ContentProviderResult()
                        {
                            Content = String.Format(_nugetBadgeFormat,
                                                    packageInfo.Id,
                                                    packageInfo.Title,
                                                    packageInfo.Summary,
                                                    projectIcon,
                                                    packageInfo.Description,
                                                    projectInfo),
                            Title = packageInfo.Title + " NuGet package"
                        };
                    }

                    return null;
                }));
            }

            return(TaskAsyncHelper.FromResult <ContentProviderResult>(null));
        }
Пример #2
0
        private void Reconnect(IConnection connection, string data)
        {
            if (CancellationToken.IsCancellationRequested)
            {
                return;
            }

            // Wait for a bit before reconnecting
            TaskAsyncHelper.Delay(ReconnectDelay).Then(() =>
            {
                // Now attempt a reconnect
                OpenConnection(connection, data, initializeCallback: null, errorCallback: null);
            });
        }
Пример #3
0
        public override async System.Threading.Tasks.Task <object> ExecuteInsertAsync <T>(Database db, DbCommand cmd, string primaryKeyName, bool useOutputClause, T poco, object[] args)
        {
            if (primaryKeyName != null)
            {
                var param = AdjustSqlInsertCommandText(cmd, primaryKeyName);
                await db.ExecuteNonQueryHelperAsync(cmd);

                return(param.Value);
            }

            await db.ExecuteNonQueryHelperAsync(cmd);

            return(TaskAsyncHelper.FromResult <object>(-1));
        }
Пример #4
0
        public void FailedWriteCompletesRequestAfterDisconnectTimeout()
        {
            var request  = new Mock <IRequest>();
            var response = new Mock <IResponse>();
            var qs       = new NameValueCollection();

            request.Setup(m => m.QueryString).Returns(new NameValueCollectionWrapper(qs));
            var url = new Uri("http://test/echo/connect");

            request.Setup(m => m.Url).Returns(url);
            request.Setup(m => m.LocalPath).Returns(url.LocalPath);
            var cts = new CancellationTokenSource();

            response.Setup(m => m.CancellationToken).Returns(cts.Token);
            response.Setup(m => m.Flush()).Returns(TaskAsyncHelper.Empty);

            var resolver    = new DefaultDependencyResolver();
            var config      = resolver.Resolve <IConfigurationManager>();
            var hostContext = new HostContext(request.Object, response.Object);

            config.DisconnectTimeout = TimeSpan.FromSeconds(6);
            var transport = new Mock <ForeverTransport>(hostContext, resolver)
            {
                CallBase = true
            };

            transport.Object.ConnectionId = "1";
            transport.Setup(m => m.Send(It.IsAny <PersistentResponse>()))
            .Returns(() =>
            {
                var task = TaskAsyncHelper.FromError(new Exception());
                cts.Cancel();
                return(task);
            });

            var connectionManager = new ConnectionManager(resolver);
            var connection        = connectionManager.GetConnectionCore("Foo");
            var wh = new ManualResetEventSlim();

            transport.Object.ProcessRequest(connection).ContinueWith(task =>
            {
                wh.Set();
            });

            connection.Broadcast("Some message");

            // 6 second disconnect timeout + 5 second disconnect threshold
            // + up to 1 second for the heartbeat to check + 3 second leeway
            Assert.True(wh.Wait(TimeSpan.FromSeconds(15)));
        }
Пример #5
0
 private void Reconnect(IConnection connection, string data, CancellationToken disconnectToken)
 {
     // Wait for a bit before reconnecting
     TaskAsyncHelper.Delay(ReconnectDelay).Then(() =>
     {
         // FIX: Race if Connection is stopped and completely restarted between checking the token and calling
         //      connection.EnsureReconnecting()
         if (!disconnectToken.IsCancellationRequested && connection.EnsureReconnecting())
         {
             // Now attempt a reconnect
             OpenConnection(connection, data, disconnectToken, initializeCallback: null, errorCallback: null);
         }
     });
 }
Пример #6
0
        public virtual Func <IHubIncomingInvokerContext, Task <object> > BuildIncoming(Func <IHubIncomingInvokerContext, Task <object> > invoke)
        {
            return(context =>
            {
                if (OnBeforeIncoming(context))
                {
                    return invoke(context).OrEmpty()
                    .Then(result => OnAfterIncoming(result, context))
                    .Catch(ex => OnIncomingError(ex, context));
                }

                return TaskAsyncHelper.FromResult <object>(null);
            });
        }
Пример #7
0
        private bool ContinueReceiving(IAsyncResult asyncResult, ReceiverContext receiverContext)
        {
            bool     shouldContinue = true;
            TimeSpan backoffAmount  = BackoffAmount;

            try
            {
                IEnumerable <BrokeredMessage> messages = receiverContext.Receiver.EndReceiveBatch(asyncResult);

                receiverContext.OnMessage(messages);

                // Reset the receive timeout if it changed
                receiverContext.ReceiveTimeout = DefaultReadTimeout;
            }
            catch (ServerBusyException ex)
            {
                receiverContext.OnError(ex);

                // Too busy so back off
                shouldContinue = false;
            }
            catch (OperationCanceledException)
            {
                // This means the channel is closed
                return(false);
            }
            catch (Exception ex)
            {
                receiverContext.OnError(ex);

                shouldContinue = false;

                // TODO: Exponential backoff
                backoffAmount = ErrorBackOffAmount;

                // After an error, we want to adjust the timeout so that we
                // can recover as quickly as possible even if there's no message
                receiverContext.ReceiveTimeout = ErrorReadTimeout;
            }

            if (!shouldContinue)
            {
                TaskAsyncHelper.Delay(backoffAmount)
                .Then(ctx => ProcessMessages(ctx), receiverContext);

                return(false);
            }

            return(true);
        }
Пример #8
0
        protected Task ProcessRequestCore(ITransportConnection connection)
        {
            Connection = connection;

            if (Context.Request.Url.LocalPath.EndsWith("/send", StringComparison.OrdinalIgnoreCase))
            {
                return(ProcessSendRequest());
            }
            else if (IsAbortRequest)
            {
                return(Connection.Abort(ConnectionId));
            }
            else
            {
                InitializePersistentState();

                if (IsConnectRequest)
                {
                    if (Connected != null)
                    {
                        // Return a task that completes when the connected event task & the receive loop task are both finished
                        bool newConnection = Heartbeat.AddConnection(this);

                        // The connected callback
                        Func <Task> connected = () =>
                        {
                            if (newConnection)
                            {
                                return(Connected().Then(() => _counters.ConnectionsConnected.Increment()));
                            }
                            return(TaskAsyncHelper.Empty);
                        };

                        return(TaskAsyncHelper.Interleave(ProcessReceiveRequestWithoutTracking, connected, connection, Completed));
                    }

                    return(ProcessReceiveRequest(connection));
                }

                if (Reconnected != null)
                {
                    // Return a task that completes when the reconnected event task & the receive loop task are both finished
                    Func <Task> reconnected = () => Reconnected().Then(() => _counters.ConnectionsReconnected.Increment());
                    return(TaskAsyncHelper.Interleave(ProcessReceiveRequest, reconnected, connection, Completed));
                }

                return(ProcessReceiveRequest(connection));
            }
        }
Пример #9
0
        public Task ProcessRequest(IReceivingConnection connection)
        {
            // This will only be called on the first request so we return a task that fires on connect

            var taskCompletionSource = new TaskCompletionSource <object>();

            _webSocketConnection.OnOpen = () =>
            {
                if (Connected != null)
                {
                    TaskAsyncHelper.Interleave(ProcessMessages, Connected, connection).ContinueWith(taskCompletionSource);
                }
                else
                {
                    // Just process messages if there's no handler
                    ProcessMessages(connection).ContinueWith(taskCompletionSource);
                }
            };

            _webSocketConnection.OnClose = () =>
            {
                _disconnected = true;

                if (Disconnected != null)
                {
                    Disconnected().Catch();
                }
            };

            _webSocketConnection.OnError = ex =>
            {
                _disconnected = true;

                if (Error != null)
                {
                    Error(ex).Catch();
                }
            };

            _webSocketConnection.OnMessage = data =>
            {
                if (Received != null)
                {
                    Received(data).Catch();
                }
            };

            return(taskCompletionSource.Task);
        }
Пример #10
0
        private Task ProcessRequestAsync(HttpListenerContext context)
        {
            try
            {
                Debug.WriteLine("Server: Incoming request to {0}.", context.Request.Url);

                PersistentConnection connection;

                string path = ResolvePath(context.Request.Url);

                if (TryGetConnection(path, out connection))
                {
                    var cts = new CancellationTokenSource();

                    // https://developer.mozilla.org/En/HTTP_Access_Control
                    string origin = context.Request.Headers["Origin"];
                    if (!String.IsNullOrEmpty(origin))
                    {
                        context.Response.AddHeader("Access-Control-Allow-Origin", origin);
                        context.Response.AddHeader("Access-Control-Allow-Credentials", "true");
                    }

                    var request     = new HttpListenerRequestWrapper(context.Request, context.User);
                    var response    = new HttpListenerResponseWrapper(context.Response, () => RegisterForDisconnect(context, cts.Cancel), cts.Token);
                    var hostContext = new HostContext(request, response);

                    if (OnProcessRequest != null)
                    {
                        OnProcessRequest(hostContext);
                    }

#if DEBUG
                    hostContext.Items[HostConstants.DebugMode] = true;
#endif
                    hostContext.Items["System.Net.HttpListenerContext"] = context;

                    // Initialize the connection
                    connection.Initialize(DependencyResolver);

                    return(connection.ProcessRequestAsync(hostContext));
                }

                return(context.Response.NotFound());
            }
            catch (Exception ex)
            {
                return(TaskAsyncHelper.FromError(ex));
            }
        }
        public TransportInitializationHandler(IHttpClient httpClient,
                                              IConnection connection,
                                              string connectionData,
                                              string transport,
                                              CancellationToken disconnectToken,
                                              TransportHelper transportHelper)
        {
            if (connection == null)
            {
                throw new ArgumentNullException("connection");
            }

            _connection      = connection;
            _httpClient      = httpClient;
            _connectionData  = connectionData;
            _transport       = transport;
            _transportHelper = transportHelper;

            _initializationTask    = new DispatchingTaskCompletionSource <object>();
            _initializationInvoker = new ThreadSafeInvoker();

            // Default event
            OnFailure = () => { };

            // We want to fail if the disconnect token is tripped while we're waiting on initialization
            try
            {
                _tokenCleanup = disconnectToken.SafeRegister(
                    _ => Fail(new OperationCanceledException(Resources.Error_ConnectionCancelled, disconnectToken)),
                    state: null);
            }
            catch (ObjectDisposedException)
            {
                // We only dispose this token after cancelling it, so consider this cancellation.
                // The ODE is only thrown on .NET 4.5.2 and below (.NET 4.6 no longer throws ODE from CTS.Register)
                Fail(new OperationCanceledException(Resources.Error_ConnectionCancelled, disconnectToken));
            }

            TaskAsyncHelper.Delay(connection.TotalTransportConnectTimeout)
            .Then(() =>
            {
                // don't timeout once connect request has finished
                if (Interlocked.CompareExchange(ref _state, InitializationState.Failed, InitializationState.Initial) ==
                    InitializationState.Initial)
                {
                    Fail(new TimeoutException(Resources.Error_TransportTimedOutTryingToConnect));
                }
            });
        }
Пример #12
0
            public void UncleanDisconnectFiresOnDisconnected()
            {
                // Arrange
                var context = new TestContext("/", new Dictionary <string, string> {
                    { "connectionToken", "1" }
                });

                var transport = new Mock <ITransport>();

                transport.SetupProperty(m => m.Disconnected);
                transport.SetupProperty(m => m.ConnectionId);
                transport.Setup(m => m.GetGroupsToken()).Returns(TaskAsyncHelper.FromResult(string.Empty));
                transport.Setup(m => m.ProcessRequest(It.IsAny <Connection>())).Returns(TaskAsyncHelper.Empty);

                var transportManager = new Mock <ITransportManager>();

                transportManager.Setup(m => m.GetTransport(context.MockHttpContext.Object)).Returns(transport.Object);

                var protectedData = new Mock <IProtectedData>();

                protectedData.Setup(m => m.Unprotect(It.IsAny <string>(), It.IsAny <string>()))
                .Returns <string, string>((value, purpose) => value);

                var connection = new Mock <PersistentConnection>()
                {
                    CallBase = true
                };
                var onDisconnectedCalled = false;

                connection.Protected().Setup("OnDisconnected", context.MockRequest.Object, "1", false).Callback(() =>
                {
                    onDisconnectedCalled = true;
                });

                var sp = ServiceProviderHelper.CreateServiceProvider(services =>
                {
                    services.AddInstance <ITransportManager>(transportManager.Object);
                    services.AddInstance <IProtectedData>(protectedData.Object);
                });

                connection.Object.Initialize(sp);

                // Act
                connection.Object.ProcessRequest(context.MockHttpContext.Object).Wait();
                transport.Object.Disconnected(/* clean: */ false);

                // Assert
                Assert.True(onDisconnectedCalled);
            }
Пример #13
0
        public Task AcceptWebSocketRequest(Func <IWebSocket, Task> callback)
        {
            var accept = Get <Action <IDictionary <string, object>, WebSocketFunc> >(OwinConstants.WebSocketAccept);

            if (accept == null)
            {
                return(TaskAsyncHelper.FromError(new InvalidOperationException("Not a web socket request")));
            }

            var options = new Dictionary <string, object>();
            var worker  = new ServerRequestWebSocket(callback);

            accept(options, worker.Invoke);
            return(TaskAsyncHelper.Empty);
        }
        public void Test_SetUnwrappedException_with_aggregate_exception_sets_inner_exception()
        {
            // Arrange
            var subEx1 = new ArgumentNullException("foo");
            var subEx2 = new InvalidOperationException("bar");
            var ex     = new AggregateException(subEx1, subEx2);

            // Act
            var task = TaskAsyncHelper.FromError(ex);

            // Assert
            Assert.That(task.Exception.InnerExceptions.Count, Is.EqualTo(2));
            Assert.That(task.Exception.InnerExceptions, Contains.Item(subEx1));
            Assert.That(task.Exception.InnerExceptions, Contains.Item(subEx2));
        }
Пример #15
0
            public void FailedNegotiateShouldBeDisconnected()
            {
                var connection = new Client.Connection("http://test");
                var transport  = new Mock <IClientTransport>();

                transport.Setup(m => m.Negotiate(connection, It.IsAny <string>()))
                .Returns(TaskAsyncHelper.FromError <NegotiationResponse>(new InvalidOperationException("Something failed.")));

                var aggEx = Assert.Throws <AggregateException>(() => connection.Start(transport.Object).Wait());
                var ex    = aggEx.Unwrap();

                Assert.IsType(typeof(InvalidOperationException), ex);
                Assert.Equal("Something failed.", ex.Message);
                Assert.Equal(ConnectionState.Disconnected, connection.State);
            }
Пример #16
0
        protected override Task <ContentProviderResult> GetCollapsibleContent(ContentProviderHttpRequest request)
        {
            var args = ExtractParameters(request.RequestUri);

            if (args == null || !args.Any())
            {
                return(TaskAsyncHelper.FromResult <ContentProviderResult>(null));
            }

            return(TaskAsyncHelper.FromResult(new ContentProviderResult()
            {
                Content = String.Format(MediaFormatString, args.ToArray()),
                Title = request.RequestUri.AbsoluteUri.ToString()
            }));
        }
Пример #17
0
        public static Task WriteAsync(this Stream stream, byte[] buffer)
        {
#if NETFX_CORE
            return(stream.WriteAsync(buffer, 0, buffer.Length));
#else
            try
            {
                return(Task.Factory.FromAsync((cb, state) => stream.BeginWrite(buffer, 0, buffer.Length, cb, state), ar => stream.EndWrite(ar), null));
            }
            catch (Exception ex)
            {
                return(TaskAsyncHelper.FromError(ex));
            }
#endif
        }
Пример #18
0
            public void FailsIfProtocolVersionIsNull()
            {
                var connection = new Connection("http://test");
                var transport  = new Mock <IClientTransport>();

                transport.Setup(m => m.Negotiate(connection)).Returns(TaskAsyncHelper.FromResult(new NegotiationResponse
                {
                    ProtocolVersion = null
                }));

                var aggEx = Assert.Throws <AggregateException>(() => connection.Start(transport.Object).Wait());
                var ex    = aggEx.Unwrap();

                Assert.IsType(typeof(InvalidOperationException), ex);
                Assert.Equal("Incompatible protocol version.", ex.Message);
            }
Пример #19
0
        protected override Task <ContentProviderResult> GetCollapsibleContent(ContentProviderHttpRequest request)
        {
            string id     = request.RequestUri.AbsoluteUri.Split('/').Last();
            string format = @"<img src=""https://i.imgur.com/{0}.jpg"" />";

            if (_config.ProxyImages)
            {
                format = @"<img src=""proxy?url=http://i.imgur.com/{0}.jpg"" />";
            }

            return(TaskAsyncHelper.FromResult(new ContentProviderResult()
            {
                Content = String.Format(format, id),
                Title = request.RequestUri.AbsoluteUri
            }));
        }
Пример #20
0
        public static Task <int> ExecuteNonQueryAsync(this IDbCommand command)
        {
            var sqlCommand = command as SqlCommand;

            if (sqlCommand != null)
            {
                return(Task.Factory.FromAsync(
                           (cb, state) => sqlCommand.BeginExecuteNonQuery(cb, state),
                           iar => sqlCommand.EndExecuteNonQuery(iar),
                           null));
            }
            else
            {
                return(TaskAsyncHelper.FromResult(command.ExecuteNonQuery()));
            }
        }
Пример #21
0
        protected override Task <ContentProviderResult> GetCollapsibleContent(ContentProviderHttpRequest request)
        {
            var match = TwitPicUrlRegex.Match(request.RequestUri.AbsoluteUri);

            if (match.Success)
            {
                var id = match.Groups["Id"].Value;
                return(TaskAsyncHelper.FromResult(new ContentProviderResult()
                {
                    Content = String.Format(_twitPicFormatString, id),
                    Title = request.RequestUri.AbsoluteUri
                }));
            }

            return(TaskAsyncHelper.FromResult <ContentProviderResult>(null));
        }
Пример #22
0
        public void FailedWriteCompletesRequestAfterDisconnectTimeout()
        {
            var request  = new Mock <IRequest>();
            var response = new Mock <IResponse>();
            var qs       = new NameValueCollection();

            qs["connectionId"] = "1";
            request.Setup(m => m.QueryString).Returns(qs);
            request.Setup(m => m.Url).Returns(new Uri("http://test/echo/connect"));
            response.Setup(m => m.EndAsync()).Returns(TaskAsyncHelper.Empty);
            bool isConnected = true;

            response.Setup(m => m.IsClientConnected).Returns(() => isConnected);
            response.Setup(m => m.FlushAsync()).Returns(TaskAsyncHelper.Empty);

            var resolver    = new DefaultDependencyResolver();
            var config      = resolver.Resolve <IConfigurationManager>();
            var hostContext = new HostContext(request.Object, response.Object);

            config.DisconnectTimeout = TimeSpan.Zero;
            config.HeartbeatInterval = TimeSpan.FromSeconds(3);
            var transport = new Mock <ForeverTransport>(hostContext, resolver)
            {
                CallBase = true
            };

            transport.Setup(m => m.Send(It.IsAny <PersistentResponse>()))
            .Returns(() =>
            {
                var task    = TaskAsyncHelper.FromError(new Exception());
                isConnected = false;
                return(task);
            });

            var connectionManager = new ConnectionManager(resolver);
            var connection        = connectionManager.GetConnection("Foo");
            var wh = new ManualResetEventSlim();

            transport.Object.ProcessRequest(connection).ContinueWith(task =>
            {
                wh.Set();
            });

            connection.Broadcast("Some message");

            Assert.True(wh.Wait(TimeSpan.FromSeconds(10)));
        }
Пример #23
0
        public Task <IResponse> Post(string url, Action <Client.Http.IRequest> prepareRequest, IDictionary <string, string> postData)
        {
            var response   = new Mock <IResponse>();
            var request    = new Mock <Client.Http.IRequest>();
            var mockStream = new MemoryStream();
            var sw         = new StreamWriter(mockStream);

            sw.Write("{}");
            sw.Flush();
            mockStream.Position = 0;

            response.Setup(r => r.GetStream()).Returns(mockStream);

            prepareRequest(request.Object);

            return(TaskAsyncHelper.FromResult <IResponse>(response.Object));
        }
Пример #24
0
        public Task AcceptWebSocketRequest(Func <IWebSocket, Task> callback)
        {
#if NET45
            var accept = _environment.Get <Action <IDictionary <string, object>, WebSocketFunc> >(OwinConstants.WebSocketAccept);
            if (accept == null)
            {
                return(TaskAsyncHelper.FromError(new InvalidOperationException("Not a web socket request")));
            }

            var options = new Dictionary <string, object>();
            var handler = new OwinWebSocketHandler(callback);
            accept(options, handler.ProcessRequestAsync);
            return(TaskAsyncHelper.Empty);
#else
            throw new NotImplementedException();
#endif
        }
Пример #25
0
        public void InvokeWithErrorInHubResultReturnsFaultedTask()
        {
            var result = new HubResult <object>
            {
                Error = "This in an error"
            };

            var connection = new Mock <SignalR.Client.IConnection>();

            connection.Setup(m => m.Send <HubResult <object> >(It.IsAny <string>()))
            .Returns(TaskAsyncHelper.FromResult(result));

            var hubProxy = new HubProxy(connection.Object, "foo");

            AssertAggregateException(() => hubProxy.Invoke("Invoke").Wait(),
                                     "This in an error");
        }
Пример #26
0
        public static Task WriteAsync(this HttpListenerResponse response, ArraySegment <byte> buffer)
        {
#if NET45
            return(response.OutputStream.WriteAsync(buffer.Array, buffer.Offset, buffer.Count));
#else
            try
            {
                return(Task.Factory.FromAsync((cb, state) => response.OutputStream.BeginWrite(buffer.Array, buffer.Offset, buffer.Count, cb, state),
                                              ar => response.OutputStream.EndWrite(ar),
                                              null));
            }
            catch (Exception ex)
            {
                return(TaskAsyncHelper.FromError(ex));
            }
#endif
        }
Пример #27
0
        public Task <IClientResponse> ProcessRequest(string url, Action <IClientRequest> prepareRequest, Dictionary <string, string> postData, bool disableWrites = false)
        {
            var uri = new Uri(url);
            PersistentConnection connection;

            if (!_shutDownToken.IsCancellationRequested && TryGetConnection(uri.LocalPath, out connection))
            {
                var tcs = new TaskCompletionSource <IClientResponse>();
                var clientTokenSource = new CancellationTokenSource();
                var request           = new Request(uri, clientTokenSource, postData, User);
                prepareRequest(request);

                Response response = null;
                response = new Response(clientTokenSource.Token, () => tcs.TrySetResult(response))
                {
                    DisableWrites = disableWrites
                };
                var hostContext = new HostContext(request, response);

                hostContext.Items[HostConstants.ShutdownToken] = _shutDownToken.Token;

                connection.Initialize(DependencyResolver, hostContext);

                connection.ProcessRequestAsync(hostContext).ContinueWith(task =>
                {
                    if (task.IsFaulted)
                    {
                        tcs.TrySetException(task.Exception);
                    }
                    else if (task.IsCanceled)
                    {
                        tcs.TrySetCanceled();
                    }
                    else
                    {
                        tcs.TrySetResult(response);
                    }

                    response.Close();
                });

                return(tcs.Task);
            }

            return(TaskAsyncHelper.FromError <IClientResponse>(new InvalidOperationException("Not a valid end point")));
        }
Пример #28
0
        private Task ProcessReceiveRequest(ITransportConnection connection)
        {
            Func <Task> initialize = null;

            // If this transport isn't replacing an existing transport, oldConnection will be null.
            ITrackingConnection oldConnection = Heartbeat.AddOrUpdateConnection(this);
            bool newConnection = oldConnection == null;

            if (IsConnectRequest)
            {
                Func <Task> connected;
                if (newConnection)
                {
                    connected = Connected ?? _emptyTaskFunc;
                    _counters.ConnectionsConnected.Increment();
                }
                else
                {
                    // Wait until the previous call to Connected completes.
                    // We don't want to call Connected twice
                    connected = () => oldConnection.ConnectTask;
                }

                initialize = () =>
                {
                    return(connected().Then((conn, id) => conn.Initialize(id), connection, ConnectionId));
                };
            }
            else
            {
                initialize = Reconnected;
            }

            var series = new Func <object, Task>[]
            {
                state => ((Func <Task>)state).Invoke(),
                state => ((Func <Task>)state).Invoke()
            };

            var states = new object[] { TransportConnected ?? _emptyTaskFunc,
                                        initialize ?? _emptyTaskFunc };

            Func <Task> fullInit = () => TaskAsyncHelper.Series(series, states).ContinueWith(_connectTcs);

            return(ProcessMessages(connection, fullInit));
        }
Пример #29
0
        private Task ConnectToRedis()
        {
            if (_connection != null)
            {
                _connection.Closed -= OnConnectionClosed;
                _connection.Error  -= OnConnectionError;
                _connection.Dispose();
                _connection = null;
            }

            // Create a new connection to redis with the factory
            RedisConnection connection = _connectionFactory();

            connection.Closed += OnConnectionClosed;
            connection.Error  += OnConnectionError;

            try
            {
                _trace.TraceInformation("Connecting...");

                // Start the connection
                return(connection.Open().Then(() =>
                {
                    _trace.TraceInformation("Connection opened");

                    // Create a subscription channel in redis
                    RedisSubscriberConnection channel = connection.GetOpenSubscriberChannel();
                    channel.CompletionMode = ResultCompletionMode.PreserveOrder;

                    // Subscribe to the registered connections
                    return channel.Subscribe(_key, OnMessage).Then(() =>
                    {
                        _trace.TraceVerbose("Subscribed to event " + _key);

                        _channel = channel;
                        _connection = connection;
                    });
                }));
            }
            catch (Exception ex)
            {
                _trace.TraceError("Error connecting to Redis - " + ex.GetBaseException());

                return(TaskAsyncHelper.FromError(ex));
            }
        }
        public override Task Send(IConnection connection, string data, string connectionData)
        {
            if (connection == null)
            {
                throw new ArgumentNullException(nameof(connection));
            }

            TaskCompletionSource <object> tcs     = new TaskCompletionSource <object>();
            EventHandler <ErrorEventArgs> onError = null;
            Action <bool> onSent = null;

            // If we don't throw here when the WebSocket isn't open, WebSocketHander.SendAsync will noop.
            if (_webSocket.ReadyState != WebSocketState.Open)
            {
                // Make this a faulted task and trigger the OnError even to maintain consistency with the HttpBasedTransports
                var ex     = new InvalidOperationException("Data can not be sent during WebSocket reconnect.");
                var result = TaskAsyncHelper.FromError(ex);

                connection.OnError(ex);
                return(result);
            }

            onError = (o, args) =>
            {
                _webSocket.OnError -= onError;
                tcs.SetException(args.ToException());
            };

            onSent = (sent) =>
            {
                _webSocket.OnError -= onError;

                if (sent)
                {
                    tcs.SetResult(null);
                }

                // onError handler is invoked, when sent == false
            };

            _webSocket.OnError += onError;
            _webSocket.SendAsync(data, onSent);

            return(tcs.Task);
        }